Elasticsearch To Eloquent Mapping
Glossary of common Elasticsearch queries and their Eloquent equivalents, providing a quick reference for developers coming from Elasticsearch to Laravel’s Eloquent.
Full Text Queries
Section titled “Full Text Queries”Match query
Section titled “Match query”Person::whereMatch('description', 'John Smith')->get();
{ "index": "people", "body": { "query": { "match": { "description": { "query": "John Smith", "operator": "and" } } }, "size": 1000 }}
Match phrase query
Section titled “Match phrase query”Person::wherePhrase('description', 'loves espressos')->get();
{ "index": "people", "body": { "query": { "match_phrase": { "description": { "query": "loves espressos" } } }, "size": 1000 }}
Match phrase prefix query
Section titled “Match phrase prefix query”Person::wherePhrasePrefix('description', 'loves es')->get();
{ "index": "people", "body": { "query": { "match_phrase_prefix": { "description": { "query": "loves es" } } }, "size": 1000 }}
Term level queries
Section titled “Term level queries”Term query
Section titled “Term query”Person::whereExact('name', 'John Smith')->get();
This will only return the documents where the name field is exactly ‘John Smith’. ‘john smith’ or ‘John’ will not be returned.
{ "index": "people", "body": { "query": { "term": { "name.keyword": { "value": "John Smith" } } }, "size": 1000 }}
Terms query
Section titled “Terms query”Product::whereIn('status', [1,5,11])->get();
{ "index": "products", "body": { "query": { "terms": { "status": [ 1, 5, 11 ] } }, "size": 1000 }}
Range query
Section titled “Range query”Product::whereBetween('in_stock', [10, 100])->get();
Find all products with an in_stock value between 10 and 100 (including 10 and 100)
{ "index": "products", "body": { "query": { "range": { "status": { "gte": 10, "lte": 100 } } }, "size": 1000 }}
Product::where('status','>=', 3)->take(10)->get();
{ "index": "products", "body": { "query": { "range": { "status": { "gte": 3 } } }, "size": 10 }}
Exists query
Section titled “Exists query”Product::whereNotIn('color', ['red','green'])->whereNotNull('color')->get();
{ "index": "products", "body": { "query": { "bool": { "must_not": [ { "terms": { "color.keyword": [ "red", "green" ] } } ], "must": [ { "exists": { "field": "color" } } ] } }, "size": 1000 }}
Product::whereNull('color')->get();
{ "index": "products", "body": { "query": { "bool": { "must_not": [ { "exists": { "field": "color" } } ] } }, "size": 1000 }}
Prefix query
Section titled “Prefix query”Person::wherePrefix('name', 'John Sm')->get();//OrPerson::whereStartsWith('name', 'John Sm')->get(); //Alias
{ "index": "people", "body": { "query": { "prefix": { "name.keyword": { "value": "John Sm" } } }, "size": 1000 }}
Regex query
Section titled “Regex query”Product::whereRegex('color', 'bl(ue)?(ack)?')->get();
The first example will return documents where the color field matches the pattern ‘bl(ue)?(ack)?’, which means it can be ‘blue’ or ‘black’. The second example will return documents where the color field matches the pattern ‘bl…*’, which means it starts with ‘bl’ and has at least three more characters. Both should return Blue or Black from the colors field.
{ "index": "products", "body": { "query": { "regexp": { "color.keyword": { "value": "bl(ue)?(ack)?" } } }, "size": 1000 }}
Fuzzy query
Section titled “Fuzzy query”Product::whereFuzzy('description', 'qick brwn fx')->get();
{ "index": "products", "body": { "query": { "fuzzy": { "description": { "value": "qick brwn fx" } } }, "size": 1000 }}
Wildcard query
Section titled “Wildcard query”Product::where('color', 'like', 'bl')->orderBy('color.keyword')->get();
{ "index": "products", "body": { "query": { "wildcard": { "color.keyword": { "value": "*bl*" } } }, "sort": [ { "color.keyword": { "order": "asc" } } ], "size": 1000 }}
Multi-match query
Section titled “Multi-match query”Best Fields
Section titled “Best Fields”Book::searchTerm('Eric')->orSearchTerm('Lean')->searchTerm('Startup')->get();
{ "index": "books", "body": { "query": { "bool": { "should": [ { "bool": { "must": [ { "multi_match": { "query": "Eric", "type": "best_fields" } } ] } }, { "bool": { "must": [ { "multi_match": { "query": "Lean", "type": "best_fields" } }, { "multi_match": { "query": "Startup", "type": "best_fields" } } ] } } ] } }, "size": 1000 }}
Most Field
Section titled “Most Field”Book::searchTermMost('quick brown fox', [ "title", "title.original", "title.shingles" ])->get();
{ "index": "books", "body": { "query": { "multi_match": { "query": "quick brown fox", "type": "most_fields", "fields": [ "title", "title.original", "title.shingles" ] } }, "size": 1000 }}
Phrase
Section titled “Phrase”Product::searchPhrase('United States')->orSearchPhrase('United Kingdom')->get();
{ "index": "products", "body": { "query": { "bool": { "should": [ { "bool": { "must": [ { "multi_match": { "query": "United States", "type": "phrase" } } ] } }, { "bool": { "must": [ { "multi_match": { "query": "United Kingdom", "type": "phrase" } } ] } } ] } }, "size": 1000 }}
Phrase Prefix
Section titled “Phrase Prefix”Person::searchPhrasePrefix('loves espressos and te')->get();
{ "index": "people", "body": { "query": { "multi_match": { "query": "loves espressos and te", "type": "phrase_prefix" } }, "size": 1000 }}
Cross Fields
Section titled “Cross Fields”Person::searchTermCross('Will Smith', [ 'first_name','last_name'],['operator' => 'and'])->get();
{ "index": "people", "body": { "query": { "multi_match": { "query": "Will Smith", "type": "cross_fields", "fields": [ "first_name", "last_name" ], "operator": "and" } }, "_source": [ "*" ] }}
Bool Prefix
Section titled “Bool Prefix”Person::searchBoolPrefix('loves espressos and te')->get();
Search for people who have the phrase ‘loves espressos and’ with a prefix of ‘ru’ in the next word in any field. Ex:
- ‘loves espressos and tea’
- ‘loves espressos and tennis’
- ‘loves espressos and tequila’
{ "index": "products", "body": { "query": { "multi_match": { "query": "loves espressos and te", "type": "bool_prefix" } }, "size": 1000 }}
Geo Queries
Section titled “Geo Queries”Geo-bounding box query
Section titled “Geo-bounding box query”// Define the top-left and bottom-right coordinates of the box$topLeft = [-10, 10]; // [latitude, longitude]$bottomRight = [10, -10]; // [latitude, longitude]
// Retrieve UserLogs where 'agent.geo' falls within the defined boxUserLog::where('status', 7)->whereGeoBox('agent.geo', $topLeft, $bottomRight)->get();
{ "index": "user_logs", "body": { "query": { "bool": { "must": [ { "term": { "status": { "value": 7 } } }, { "geo_bounding_box": { "agent.geo": { "top_left": [ -180, 90 ], "bottom_right": [ 180, -90 ] } } } ] } }, "size": 1000 }}
Geo-distance query
Section titled “Geo-distance query”// Specify the central point and radius$point = [ 'lat' => 51.509865, 'lon' => -0.118092,]; //or:$point = [51.509865, -0.118092]; // [latitude, longitude]$distance = '20km';
// Retrieve UserLogs with Status 7 where 'agent.geo' is within 20km of center of LondonUserLog::where('status', 7)->whereGeoDistance('agent.geo', $distance, $point)->get();
{ "index": "user_logs", "body": { "query": { "bool": { "must": [ { "term": { "status": { "value": 7 } } }, { "geo_distance": { "agent.geo": [ 51.509865, -0.118092 ], "distance": "20km" } } ] } }, "size": 1000 }}