Skip to content

Full-text Search

Not a search driver. The full Elasticsearch query builder, returning your Laravel models.

viaIndex() gives you access to every query method from Laravel-Elasticsearch. 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, viaIndex() drops you into the Elasticsearch query builder:

User::viaIndex()->searchTerm('suvi')->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 request Index Models directly when you need them:

MethodReturns
get() / paginate() / first()Base models (User)
getBase() / paginateBase() / firstBase()Base models (explicit)
getIndex() / paginateIndex() / firstIndex()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().


Multi-match queries across all indexed fields.

// Term search - finds "nara" across all fields
User::viaIndex()->searchTerm('nara')->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('suvi', ['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. They 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', '%max%')->get();

Chain them with search methods for 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 ->

Query embedded relations with dot notation. No special syntax needed:

// Users with profiles mentioning "elasticsearch"
User::viaIndex()->where('profiles.about', 'like', '%elasticsearch%')->get();
// Combine embedded fields with other filters
User::viaIndex()
->where('state', 'active')
->where('logs.action', 'login')
->where('logs.created_at', '>=', now()->subWeek())
->get();

If you’ve set up explicit nested mappings in your migrationMap(), use whereNestedObject() for 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 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:

  • 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