Skip to content

Search is only available in production builds. Try building and previewing the site to test it out locally.

OpenSearch To Eloquent Mapping

This content is for v1/2. Switch to the latest version for up-to-date documentation.

Glossary of common OpenSearch queries and their Eloquent equivalents, providing a quick reference for developers coming from OpenSearch to Laravel’s Eloquent.

Full Text Queries

Match query

$products = Product::where('manufacturer.country', 'England')->take(10)->get();
{
"index": "products",
"body": {
"query": {
"match": {
"manufacturer.country": "England"
}
},
"_source": [
"*"
]
},
"size": 10
}

Match phrase query

return Person::wherePhrase('description', 'loves espressos')->get();
{
"index": "people",
"body": {
"query": {
"match_phrase": {
"description": "loves espressos"
}
},
"_source": [
"*"
]
}
}

Match phrase prefix query

return Person::wherePhrasePrefix('description', 'loves es')->get();
{
"index": "people",
"body": {
"query": {
"match_phrase_prefix": {
"description": "loves es"
}
},
"_source": [
"*"
]
}
}

Term level queries

Term query

return 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": "John Smith"
}
},
"_source": [
"*"
]
}
}

Terms query

$products = Product::whereIn('status', [1,5,11])->get();
{
"index": "products",
"body": {
"query": {
"terms": {
"status": [
1,
5,
11
]
}
},
"_source": [
"*"
]
}
}

Range query

$products = 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": {
"in_stock": {
"gte": 10,
"lte": 100
}
}
},
"_source": [
"*"
]
}
}
$products = Product::where('status','>=', 3)->take(10)->get();
{
"index": "products",
"body": {
"query": {
"range": {
"status": {
"gte": 3
}
}
},
"_source": [
"*"
]
},
"size": 10
}

Exists query

$products = Product::whereNotIn('color', ['red','green'])->whereNotNull('color')->get();
{
"index": "products",
"body": {
"query": {
"bool": {
"must": [
{
"bool": {
"must_not": {
"terms": {
"color": [
"red",
"green"
]
}
}
}
},
{
"exists": {
"field": "color"
}
}
]
}
},
"_source": [
"*"
]
}
}
$products = Product::whereNull('color')->get();
{
"index": "products",
"body": {
"query": {
"bool": {
"must_not": [
{
"exists": {
"field": "color"
}
}
]
}
},
"_source": [
"*"
]
}
}

Fuzzy query

Prefix query

Wildcard query

$products = Product::where('color', 'like', 'bl')->orderBy('color.keyword')->get();
{
"index": "products",
"body": {
"query": {
"query_string": {
"query": "color:*bl*"
}
},
"_source": [
"*"
],
"sort": [
{
"color.keyword": {
"order": "asc"
}
}
]
}
}

Multi-match query

Best Fields

$results = Book::searchTerm('Eric')->orSearchTerm('Lean')->searchTerm('Startup')->get();

Search for books that contain ‘Eric’ or (‘Lean’ and ‘Startup’)

{
"index": "books",
"body": {
"query": {
"bool": {
"should": [
{
"bool": {
"must": [
{
"multi_match": {
"query": "Eric",
"type": "best_fields",
"fields": [
"*"
]
}
}
]
}
},
{
"bool": {
"must": [
{
"multi_match": {
"query": "Lean",
"type": "best_fields",
"fields": [
"*"
]
}
},
{
"multi_match": {
"query": "Startup",
"type": "best_fields",
"fields": [
"*"
]
}
}
]
}
}
]
}
},
"_source": [
"*"
]
}
}

Most Field

$results = Book::searchTermMost('quick brown fox', [ "title", "title.original", "title.shingles" ])->get();

Search for books that contain ‘quick brown fox’ in the ‘title’, ‘title.original’, or ‘title.shingles’ fields

{
"index": "books",
"body": {
"query": {
"multi_match": {
"query": "quick brown fox",
"type": "most_fields",
"fields": [
"title",
"title.original",
"title.shingles"
]
}
},
"_source": [
"*"
]
}
}

Phrase

Product::searchPhrase('United States')->orSearchPhrase('United Kingdom')->get();
{
"index": "products",
"body": {
"query": {
"bool": {
"should": [
{
"bool": {
"must": [
{
"multi_match": {
"query": "United States",
"type": "phrase",
"fields": [
"*"
]
}
}
]
}
},
{
"bool": {
"must": [
{
"multi_match": {
"query": "United Kingdom",
"type": "phrase",
"fields": [
"*"
]
}
}
]
}
}
]
}
},
"_source": [
"*"
]
}
}

Phrase Prefix

$results = Person::searchPhrasePrefix('loves espressos and te')->get();
{
"index": "people",
"body": {
"query": {
"multi_match": {
"query": "loves espressos and te",
"type": "phrase_prefix",
"fields": [
"*"
]
}
},
"_source": [
"*"
]
}
}

Cross Fields

$results = 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

$results = 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": "people",
"body": {
"query": {
"multi_match": {
"query": "loves espressos and te",
"type": "bool_prefix",
"fields": [
"*"
]
}
},
"_source": [
"*"
]
}
}

Geo Queries

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 box
$logs = UserLog::where('status', 7)->filterGeoBox('agent.geo', $topLeft, $bottomRight)->get();
{
"index": "user_logs",
"body": {
"query": {
"bool": {
"must": [
{
"match": {
"status": 7
}
}
],
"filter": {
"geo_bounding_box": {
"agent.geo": {
"top_left": [
-10,
10
],
"bottom_right": [
10,
-10
]
}
}
}
}
},
"_source": [
"*"
]
}
}

Geo-distance query

// Specify the central point and radius
$point = [0, 0]; // [latitude, longitude]
$distance = '20km';
// Retrieve UserLogs where 'agent.geo' is within 20km of the specified point
$logs = UserLog::where('status', 7)->filterGeoPoint('agent.geo', $distance, $point)->get();
{
"index": "user_logs",
"body": {
"query": {
"bool": {
"must": [
{
"match": {
"status": 7
}
}
],
"filter": {
"geo_distance": {
"distance": "20km",
"agent.geo": {
"lat": 0,
"lon": 0
}
}
}
}
},
"_source": [
"*"
]
}
}