Elasticsearch Specific Queries
Elasticsearch offers a rich set of query capabilities, including geospatial queries and regex-based searches, which go beyond the traditional query types found in SQL databases. The Laravel-Elasticsearch integration provides a seamless interface to leverage these powerful features directly within your Laravel models.
GeoBox
The filterGeoBox
method allows you to retrieve documents based on geospatial data, specifically targeting documents where a geo-point field falls within a defined "box" on a map. This is particularly useful for applications requiring location-based filtering, such as finding all events within a specific geographical area.
// 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();
GeoPoint
The filterGeoPoint
method filters results based on their proximity to a given point, specified by latitude and longitude, within a certain radius.
// 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();
The $distance
parameter is a string combining a numeric value and a distance unit (e.g., km for kilometers, mi for miles). Refer to the Elasticsearch documentation on distance units for more information.
The field must be of type geo for both filterGeoBox
and filterGeoPoint
methods otherwise your shards will fail, make sure to set the geo field in your migration, ex:
Schema::create('user_logs',function (IndexBlueprint $index){
$index->geo('agent.geo');
});
For more details, see Migrations
WhereExact
This method allows you to query for exact case-sensitive matches within a field. This is useful when you need to find a specific value. Keep in mind that the field will also need to have a keyword mapping.
Under the hood, this method uses the term
query from Elasticsearch's Query DSL.
return Person::whereExact('name', 'John Smith')->get();
WherePhrase
This method allows you to query for exact phrases within a field. This is useful when you need to search for a specific sequence of words within a text field.
Under the hood, this method uses the match_phrase
query from Elasticsearch's Query DSL.
return Person::wherePhrase('description', 'loves espressos')->get();
WherePhrasePrefix
Similar to WherePhrase
, this method allows you to query for exact phrases where the last word starts with a particular prefix.
Under the hood, this method uses the match_phrase_prefix
query from Elasticsearch's Query DSL.
return Person::wherePhrasePrefix('description', 'loves es')->get();
WhereTimestamp
This method allows you to query for timestamps on a known field and will sanitize the input to ensure it is a valid timestamp for both seconds and milliseconds.
return Product::whereTimestamp('last_viewed', '<=', 1713911889521)->get();
WhereRegex
The WhereRegex
method allows you to query for documents based on a regular expression pattern within a field.
$regex1 = Product::whereRegex('color', 'bl(ue)?(ack)?')->get();
$regex2 = Product::whereRegex('color', 'bl...*')->get();
RAW DSL Queries
For scenarios where you need the utmost flexibility and control over your Elasticsearch queries, the Laravel-Elasticsearch integration provides the capability to directly use Elasticsearch's Query DSL (Domain Specific Language). The results will still be returned as collections of Eloquent models.
$bodyParams = [
'query' => [
'match' => [
'color' => 'silver',
],
],
];
return Product::rawSearch($bodyParams); //Will search within the products index
return Product::rawSearch($bodyParams,true); //Will return the raw response from Elasticsearch
RAW Aggregation Queries
Similar to raw search queries, you can also execute raw aggregation queries using Elasticsearch's Aggregation DSL. This allows you to perform complex aggregations on your data and retrieve the results in a structured format.
$body = [
'aggs' => [
'price_ranges' => [
'range' => [
'field' => 'price',
'ranges' => [
['to' => 100],
['from' => 100, 'to' => 500],
['from' => 500, 'to' => 1000],
['from' => 1000],
],
],
'aggs' => [
'sales_over_time' => [
'date_histogram' => [
'field' => 'datetime',
'fixed_interval' => '1d',
],
],
],
],
],
];
return Product::rawAggregation($body);
To DSL
This method returns the parsed DSL query from the query builder. This can be useful when you need to inspect the raw query being generated by the query builder.
$query = Product::where('price', '>', 100)->toDSL();
toDsl()
and the inherited toSQL()
are the same method. You can use them interchangeably.