provydon/laravel-pgsearch

PostgreSQL-friendly search for Eloquent (ILIKE + normalization; optional FTS/trigram later).

v1.4.0 2025-08-08 05:42 UTC

This package is auto-updated.

Last update: 2025-08-08 05:43:56 UTC


README

Smart PostgreSQL search for Laravel with text normalization and relationship support.

PHP Version Laravel Version PostgreSQL License Tests

โœจ 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:

Buy Me A Coffee

๐Ÿ“ License

MIT License - see LICENSE for details.

Made with โค๏ธ for the Laravel community