Laravel Searchable

v 1.4.*

Advanced Usage

Searching Across Relationships

Search through related models seamlessly:

$searchQuery = request('search_query'); // e.g., 'bangladesh'

$users = User::search($searchQuery, [
    '%name',
    '%email',
    '%phone',
    'country|%name',              // Search in related country's name
    'country.city|%name'          // Search in nested relationship
])->get();

Relationship syntax:

  • relationship|%field - Search a related model's field
  • relationship.nested|%field - Search through nested relationships

Generated SQL equivalent:

User::where('name', 'like', '%' . $searchQuery . '%')
    ->orWhere('email', 'like', '%' . $searchQuery . '%')
    ->orWhere('phone', 'like', '%' . $searchQuery . '%')
    ->orWhereHas('country', function ($query) use ($searchQuery) {
        $query->where('name', 'like', '%' . $searchQuery . '%');
    })
    ->orWhereHas('country.city', function ($query) use ($searchQuery) {
        $query->where('name', 'like', '%' . $searchQuery . '%');
    })
    ->get();

Search across multiple fields combined together (useful for full names, addresses, etc.):

$searchQuery = request('search_query');

$users = User::search($searchQuery, [
    '%first_name',
    '%last_name',
    '%first_name+last_name',      // Search full name
])->get();

Concatenation syntax:

  • %field1+field2 - Combines fields with a space separator

Generated SQL equivalent:

User::where('first_name', 'like', '%' . $searchQuery . '%')
    ->orWhere('last_name', 'like', '%' . $searchQuery . '%')
    ->orWhere(DB::raw("concat(first_name, ' ', last_name)"), 'LIKE', '%' . $searchQuery . '%')
    ->get();

Chaining Multiple Search Conditions

Combine multiple search criteria by chaining search() methods:

$searchQuery = request('search_query');
$status = request('status');

$users = User::search($searchQuery, [
        '%first_name',
        '%last_name',
        '%first_name+last_name',
    ])
    ->search($status, ['status'])      // Add additional condition
    ->get();

Generated SQL equivalent:

User::where('first_name', 'like', '%' . $searchQuery . '%')
    ->orWhere('last_name', 'like', '%' . $searchQuery . '%')
    ->orWhere(DB::raw("concat(first_name, ' ', last_name)"), 'LIKE', '%' . $searchQuery . '%')
    ->where('status', $status)
    ->get();

Date Searching

Filter records by a specific date with comparison operators:

$status = request('status');
$date = request('date'); // e.g., '2020-01-01'

$users = User::search($status, ['status'])
    ->searchDate($date, ['created_at'], '>')
    ->get();

Supported operators:

  • > - Greater than
  • < - Less than
  • = - Equal to
  • >= - Greater than or equal to
  • <= - Less than or equal to

Generated SQL equivalent:

User::where('status', $status)
    ->whereDate('created_at', '>', $date)
    ->get();

Filter records within a date range:

$status = request('status');
$dateRange = request('date_range'); // e.g., '2020-01-01 - 2020-01-31'

$users = User::search($status, ['status'])
    ->searchDate($dateRange, ['created_at'], '><')
    ->get();

Date range format:

  • Must be separated by - (space, hyphen, space)
  • Format: YYYY-MM-DD - YYYY-MM-DD

Operator for ranges:

  • >< - Between dates (inclusive)

Generated SQL equivalent:

$startDate = explode(' - ', $dateRange)[0];
$endDate = explode(' - ', $dateRange)[1];
$start = Carbon::parse($startDate);
$end = Carbon::parse($endDate);

User::where('status', $status)
    ->whereBetween('created_at', [$start, $end])
    ->get();

Date Search with Relationships

Coming Soon

This feature will allow you to filter by dates in related models.

Date Range Search with Relationships

Coming Soon

This feature will allow you to filter by date ranges in related models.


Complete Example

Here's a real-world example combining multiple search features:

public function index(Request $request)
{
    $users = User::query()
        // Text search across multiple fields
        ->search($request->search_query, [
            '%first_name',
            '%last_name',
            '%first_name+last_name',
            '%email',
            'country|%name',
        ])
        // Filter by status
        ->search($request->status, ['status'])
        // Filter by role
        ->search($request->role, ['role'])
        // Date range filter
        ->searchDate($request->date_range, ['created_at'], '><')
        // Pagination
        ->paginate(20);
    
    return view('users.index', compact('users'));
}

Example URL:

http://example.com/users?search_query=john&status=1&role=admin&date_range=2020-01-01 - 2020-01-31