Skip to content

Full-text Search

This isn’t a search driver. It’s the full Elasticsearch query builder, returning your Laravel models.

viaIndex() gives you access to every query method from the Laravel-Elasticsearch package. Full-text search, geo queries, fuzzy matching, regex, nested objects, aggregations, highlighting - the works.

The search() convenience method runs a phrase prefix search across all fields:

User::search('loves espressos');

Returns a Collection of User models. Good for search bars and quick lookups.

For everything else, use viaIndex() to enter the Elasticsearch query builder:

User::viaIndex()->searchTerm('david')->get(); // Collection of User models
User::viaIndex()->where('state', 'active')->paginate(); // Paginator of User models
User::viaIndex()->searchPhrase('ice bathing')->first(); // User model or null

Results come back as your Base Models by default. You can also request Index Models directly:

MethodReturns
get() / paginate() / first()Base models (User)
getBase() / paginateBase()Base models (explicit)
getIndex() / paginateIndex()Index models (IndexedUser)

Use getIndex() when you need access to embedded fields or search highlights on the index model itself. Convert back anytime with ->asBase().


Search across all indexed fields with multi-match queries.

// Term search - finds "david" across all fields
User::viaIndex()->searchTerm('david')->get();
// Phrase search - exact word sequence
User::viaIndex()->searchPhrase('ice bathing')->get();
// Fuzzy search - handles typos
User::viaIndex()->searchFuzzy('quikc brwn foks')->get();
// Phrase prefix - autocomplete-style matching
User::viaIndex()->searchPhrasePrefix('loves espr')->get();

Boost specific fields to control relevance:

User::viaIndex()->searchTerm('david', ['first_name^3', 'last_name^2', 'bio'])->first();

Also available: searchBoolPrefix(), searchTermMost(), searchTermCross(), searchQueryString()

Full reference: Search Queries →

Target specific fields with Elasticsearch-native query types.

// Regex on a single field
User::viaIndex()->whereRegex('favorite_color', 'bl(ue)?(ack)?')->get();
// Fuzzy match on a single field
User::viaIndex()->whereFuzzy('last_name', 'phillp')->get();
// Match with operator control
User::viaIndex()->whereMatch('bio', 'laravel elasticsearch', 'and')->get();

Also available: whereTerm(), whereExact(), wherePrefix(), wherePhrase(), wherePhrasePrefix(), whereScript()

Full reference: Elasticsearch Queries →

All the familiar Laravel query methods work exactly as you’d expect.

User::viaIndex()->where('state', 'active')->get();
User::viaIndex()->where('orders', '>=', 10)->get();
User::viaIndex()->whereIn('state', ['active', 'pending'])->get();
User::viaIndex()->whereBetween('created_at', [$start, $end])->get();
User::viaIndex()->whereNull('deleted_at')->get();
User::viaIndex()->where('name', 'like', '%david%')->get();

Chain them with search methods for powerful filtered searches:

User::viaIndex()
->searchTerm('elasticsearch')
->where('state', 'active')
->whereBetween('created_at', [now()->subYear(), now()])
->orderByDesc('created_at')
->paginate(10);
Full reference: Eloquent Queries →

Filter and sort by geographic distance.

// Find users within 5km of a point
User::viaIndex()
->filterGeoPoint('home.location', '5km', [40.7128, -74.0060])
->orderByGeo('home.location', [40.7128, -74.0060])
->get();
// Bounding box filter
User::viaIndex()
->filterGeoBox('home.location', [41.0, -74.5], [40.5, -73.5])
->get();
Full reference: Geo Queries →

Search across embedded relations as nested objects.

// Users with profiles mentioning "elasticsearch"
User::viaIndex()->whereNestedObject('profiles', function ($query) {
$query->where('profiles.about', 'like', '%elasticsearch%');
})->get();
// Combine nested with other filters
User::viaIndex()
->where('state', 'active')
->whereNestedObject('logs', function ($query) {
$query->where('logs.action', 'login')
->where('logs.created_at', '>=', now()->subWeek());
})
->get();
Full reference: Nested Queries →

Run analytics directly on your indexed data.

User::viaIndex()->where('state', 'active')->avg('orders');
User::viaIndex()->where('state', 'active')->sum('revenue');
User::viaIndex()->min('created_at');
User::viaIndex()->max('last_login');
// Distinct values
User::viaIndex()->distinct('state');
// Group by with aggregations
User::viaIndex()->groupBy('state')->get();

Also available: stats(), percentiles(), cardinality(), extendedStats(), matrix(), boxplot(), medianAbsoluteDeviation()

Full reference: Aggregations →

Get search highlights showing exactly where terms matched. Use getIndex() to access the highlights on the index model.

$results = User::viaIndex()
->searchTerm('espresso')
->withHighlights()
->getIndex();
foreach ($results as $indexedUser) {
$indexedUser->getHighlights(); // ['bio' => ['Loves <em>espresso</em> and jazz']]
}

Custom highlight tags:

User::viaIndex()
->searchTerm('espresso')
->withHighlights('<mark>', '</mark>')
->getIndex();

Every query method available through viaIndex() is documented in the Laravel-Elasticsearch package docs:

  • Search Queries - searchTerm, searchPhrase, searchFuzzy, searchPhrasePrefix, searchBoolPrefix, searchQueryString
  • Elasticsearch Queries - whereMatch, whereRegex, whereFuzzy, whereTerm, wherePrefix, wherePhrase, geo queries
  • Eloquent Queries - where, whereIn, whereBetween, whereNull, whereDate, like, orWhere
  • Nested Queries - whereNestedObject, whereNotNestedObject, filterNested, orderByNested
  • Aggregations - avg, sum, min, max, stats, percentiles, distinct, groupBy, cardinality
  • Ordering & Pagination - orderBy, orderByGeo, orderByNested, paginate, skip, take