provydon / laravel-pgsearch
PostgreSQL-friendly search for Eloquent (ILIKE + normalization; optional FTS/trigram later).
v1.4.0
2025-08-08 05:42 UTC
Requires
- php: >=8.1
- illuminate/database: ^10.0|^11.0|^12.0
- illuminate/support: ^10.0|^11.0|^12.0
Requires (Dev)
- laravel/pint: ^1.24
- orchestra/testbench: ^8.0|^9.0|^10.0
- pestphp/pest: ^2.34
- pestphp/pest-plugin-laravel: ^2.4
- phpunit/phpunit: ^10.0|^11.0
README
Smart PostgreSQL search for Laravel with text normalization and relationship support.
โจ Why This Package?
- ๐ฏ Smart matching: Find "Jane Doe" even when stored as "Jane-Doe"
- ๐ฑ Phone numbers: Search "1234567890" matches "(123) 456-7890"
- ๐ Relationships: Search across related models seamlessly
- โก PostgreSQL optimized: Uses ILIKE and REGEXP_REPLACE for performance
- ๐ก๏ธ Safe fallback: Works on non-PostgreSQL databases (no-op)
๐ Quick Start
Install
composer require provydon/laravel-pgsearch
Use Immediately
// Search users User::query()->pgSearch('john doe', ['name', 'email'])->get(); // Search with relationships Post::query()->pgSearch('jane', ['title', 'user.name'])->get(); // Phone number search User::query()->pgSearch('1234567890', ['phone'])->get(); // Or use the helper function pg_search(User::query(), 'john doe', ['name', 'email'])->get();
That's it! No configuration needed.
๐ Usage Examples
Basic Search
// Single column User::query()->pgSearch('john', ['name'])->get(); // Multiple columns User::query()->pgSearch('example', ['name', 'email'])->get();
Relationship Search
// Search posts by author name Post::query()->pgSearch('jane doe', ['title', 'user.name'])->get(); // Search orders by customer info Order::query()->pgSearch('smith', ['number', 'customer.name', 'customer.email'])->get();
Advanced Options
// Disable text normalization User::query()->pgSearch('exact-match', ['name'], ['normalize' => false])->get(); // Chain with other query methods User::query() ->where('active', true) ->pgSearch('john', ['name']) ->orderBy('created_at') ->paginate(15);
Helper Function
For convenience, you can also use the pg_search()
helper function:
// Using the helper function $users = pg_search(User::query(), 'john doe', ['name', 'email'])->get(); // With options $users = pg_search(User::query(), 'john', ['name'], ['normalize' => false])->get(); // In controllers public function search(Request $request) { $query = User::query()->where('active', true); if ($request->has('search')) { $query = pg_search($query, $request->search, ['name', 'email']); } return $query->paginate(15); }
๐ง Configuration (Optional)
Publish config to customize behavior:
php artisan vendor:publish --tag=pgsearch-config
// config/pgsearch.php return [ 'normalize' => true, // Enable smart text matching ];
๐ง How It Works
The package performs intelligent PostgreSQL searches:
Search Type | SQL Example | Matches |
---|---|---|
Direct | name ILIKE '%john doe%' |
"John Doe", "JOHN DOE" |
Normalized | REGEXP_REPLACE(phone, '[^a-zA-Z0-9]', '', 'g') ILIKE '%1234567890%' |
"(123) 456-7890", "123-456-7890" |
Real-World Examples
// These all find the same user: User::query()->pgSearch('Jane Doe', ['name'])->get(); // Direct match User::query()->pgSearch('jane doe', ['name'])->get(); // Case insensitive User::query()->pgSearch('janedoe', ['name'])->get(); // Normalized match // Phone number variations: User::query()->pgSearch('1234567890', ['phone'])->get(); // Finds all these: // "(123) 456-7890", "123-456-7890", "123.456.7890", "123 456 7890"
๐ Requirements
- Laravel: 10.0+, 11.0+, or 12.0+
- PHP: 8.1+
- Database: PostgreSQL (graceful fallback for others)
โก Performance Tips
For frequently searched columns, add expression indexes to speed up normalized searches:
-- For phone number searches CREATE INDEX users_phone_normalized_idx ON users (REGEXP_REPLACE(phone::text, '[^a-zA-Z0-9]', '', 'g')); -- For name searches CREATE INDEX users_name_normalized_idx ON users (REGEXP_REPLACE(name::text, '[^a-zA-Z0-9]', '', 'g'));
Important: Use the exact same expression as in the search query for optimal performance.
๐งช Testing
# Create test database createdb pg-search # Run tests composer test
๐ Support
If this package helped you, consider supporting its development:
๐ License
MIT License - see LICENSE for details.
Made with โค๏ธ for the Laravel community