georgebohnisch / laravel-elasticsearch-query-builder
:Query Elasticsearch by using Eloquent
Installs: 112
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 8
pkg:composer/georgebohnisch/laravel-elasticsearch-query-builder
Requires
- elasticsearch/elasticsearch: ^6.0.1
- illuminate/support: ~5
Requires (Dev)
- mockery/mockery: ^1.1
- orchestra/testbench: ~3.0
- phpunit/phpunit: ~7.0
- sempro/phpunit-pretty-print: ^1.0
This package is not auto-updated.
Last update: 2025-11-07 11:58:50 UTC
README
Query Elasticsearch by using Eloquent
This Laravel package is developed to simplify the process of querying Elasticsearch. Eloquent is a powerful tool to access and manipulate data in RDB. However, it is not designed to query no-sql DB like Elasticsearch. This package is made to fill the gap between the most popular ORM in Laravel and Elasticsearch.
The package only relies on the official PHP Elasticsearch package(v6).
PHP version
The package is developed and tested under PHP v7.1. It should be also compatible with v7.*. Please email me if you find any compatibility issue.
Elasticsearch version
The package is developed and tested under Elasticsearch v6.*. It should be also compatible with v5.*. Please email me if you find any compatibility issue. It is confirmed that the package does not support versions before v5.*.
Installation
-
Add the following to your
composer.jsonfile:"shisun/laravel-elasticsearch-query-builder": "dev-master"
-
Run
composer updatein terminal -
Add the package to your
app.phpfile in the config folder:'providers' => [ ... Shisun\LaravelElasticsearchQueryBuilder\LaravelElasticsearchQueryBuilderServiceProvider::class, ]
-
If your Elasticsearch is not accessible at
localhost:9200then you have to publish the config file by running:$ php artisan vendor:publish --provider="Shisun\LaravelElasticsearchQueryBuilder\LaravelElasticsearchQueryBuilderServiceProvider" -
(Optional) Change the
ES_HOSTSin config/laravel-elasticsearch-query-builder.php to the address of your Elasticsearch -
Use with Eloquent Model
- Add
EsTraitto your modeluse Shisun\LaravelElasticsearchQueryBuilder\EsTrait; class User extends Model { use EsTrait; }
- Enable validation(Optional)
use Shisun\LaravelElasticsearchQueryBuilder\EsTrait; class User extends Model { use EsTrait; public $mappingProperties; public function __construct($attributes = []) { parent::__construct($attributes); $this->mappingProperties = [ 'id' => [ 'type' => 'integer', ], 'name' => [ 'type' => 'text', 'index' => true, ], 'email' => [ 'type' => 'keyword' ], 'address' => [ 'type' => 'text' ], 'float_example' => [ 'type' => 'float' ], 'multi_fields_example' => [ 'type' => 'text', 'fields' => [ 'raw' => [ 'type' => 'keyword' ] ] ], 'created_at' => [ 'type' => 'date', 'format' => 'yyyy-MM-dd HH:mm:ss', ], 'some_relations' => [ 'type' => 'nested', 'properties' => [ .... ] ] ]; } }
- Set model-level Index and Type name. Add follow two functions to your model.(Optional)
public function getIndexName() { return 'users'; } // type name will be set to index name if this function is not defined. public function getTypeName() { return 'users'; }
- Add
-
Use without Eloquent
use Shisun\LaravelElasticsearchQueryBuilder\LaravelElasticsearchQueryBuilder as Builder; $query = (new Builder())->setOptions([ 'index_name' => 'users', 'type_name' => 'users' ])->where('name', 'Leo')->get()->toArray(); // or if you only want to generate the query without getting results $query = (new Builder())->where('name', 'Leo')->getBody()
Usage
Table of Contents
- Init & Configs
- __construct
- setOptions
- getters
- getIndexName
- getTypeName
- getValidation
- getMappingProperties
- setters
- setIndexName
- setTypeName
- setValidation
- setMappingProperties
- Query Clauses
- Order
- Pagination
- Aggregation
- Other Filters
- Execute Query
- Results Manipulation
- Direct Query Output
Init & Configs
__construct
-
You do not need to use this function if you use Eloquent
-
Parameters
Name Required Type Default Description model Eloquent,nullnull -
Output
self -
Examples
- basic example
use Shisun\LaravelElasticsearchQueryBuilder\LaravelElasticsearchQueryBuilder as Builder; $builder = new Builder();
- basic example
setOptions
-
You do not need to use this function if you use Eloquent
-
Parameters
Name Required Type Default Description options Y array -
Output
self -
Examples
- Basic
use Shisun\LaravelElasticsearchQueryBuilder\LaravelElasticsearchQueryBuilder as Builder; $builder = (new Builder())->setOptions([ 'index_name' => 'users', 'type_name' => 'users', 'validation' => false, 'mapping_properties' => [check the example in the installation section] ]);
- Basic
Query Clauses
where
-
Parameters
Name Required Type Default Description column Y callable,stringoperator stringnull=,>,<,<=,>=,!=,*value mixednullor boolfalseboost bool,intfalseThe weight of the column -
Output
self -
Examples
=can be ignoredUser::es()->where('id', 1)->first()
*is the wildcard operator// Find the user whose name starts with 'Leo' User::es()->where('name', '*', 'Leo*')->first()
columncan be a functionUser::es()->where(function($q) { $q->orWhere(...)->orWhere(...); })->get()->toArray()
whereNull
-
Parameters
Name Required Type Default Description column Y stringColumn or relation -
Output
self -
Examples
- Find all users with no name
User::es()->whereNull('name')->get()
- Find all users who don't have address
User::es()->whereNull('Addresses')->get()
- Find all users with no name
whereNotNull
-
Parameters
Name Required Type Default Description column Y stringColumn or relation -
Output
self -
Examples
- Find all users with a name
User::es()->whereNotNull('name')->get()
- Find all users who have at least one address
User::es()->whereNotNull('Addresses')->get()
- Find all users with a name
orWhere
-
Parameters
Name Required Type Default Description column Y callable,stringoperator stringnull=,>,<,<=,>=,like,!=,*value mixednullboost bool,intfalseThe weight of the column -
Output
self -
Examples
=can be ignoredUser::es()->orWhere('id', 1)->first()
columncan be a functionUser::es()->orWhere(function($q) { $q->where(...)->where(...); })->limit(1)->get()->toArray()
whereMatch
-
It is used to make fuzzy text search. This function should only be applied on text fields.
-
Parameters
Name Required Type Default Description column Y stringvalue mixednulloptions array[] matchquery options. Check elasticsearch Docs for references -
Output
self -
Examples
- without
optionsUser::es()->whereMatch('email', 'shisun@')->first()
- with
optionsUser::es()->whereMatch('email', 'shisun@', [ 'query' => 'this will be overrided by $value', 'operator' => 'and', 'zero_terms_query' => 'all' ])->first()
- without
whereDoesntMatch
-
Parameters
Name Required Type Default Description column Y stringvalue mixednulloptions array[] matchquery options. Check elasticsearch Docs for references -
Output
self -
Examples
- without
optionsUser::es()->whereDoesntMatch('email', 'shisun@')->first()
- with
optionsUser::es()->whereDoesntMatch('email', 'shisun@', [ 'query' => 'this will be overrided by $value', 'operator' => 'and', 'zero_terms_query' => 'all' ])->first()
- without
orWhereMatch
-
Parameters
Name Required Type Default Description column Y stringvalue mixednulloptions array[] matchquery options. Check elasticsearch Docs for references -
Output
self -
Examples
- without
optionsUser::es()->orWhereMatch('email', 'shisun@')->first()
- with
optionsUser::es()->orWhereMatch('email', 'shisun@', [ 'query' => 'this will be overrided by $value', 'operator' => 'and', 'zero_terms_query' => 'all' ])->first()
- without
whereHas
-
Parameters
Name Required Type Default Description relation Y string,callableMust be capitalized closure callable,nullnullfromandtocannot be bothnullor booleannullfor internal use. See orWhereHas boost boolean,integerfalseUsed to adjust the weight of the condition -
Output
self -
Examples
- basic example
// find all users with active someRelations User::es()->whereHas('someRelations', function($q) { $q->where('status', 'active'); })->first();
- first parameter can be a function
// find all users with either active someRelations or red someOtherRelations // Note: the parent 'whereHas' is interchangable with 'where' clause User::es()->whereHas(function($q) { $q->orWhereHas('someRelations', function($k) { $k->where('status', 'active'); })->orWhereHas('someOtherRelations', function($k) { $k->where('color', 'red'); }); })->first();
- basic example
orWhereHas
-
Parameters
Name Required Type Default Description relation Y string,callableMust be capitalized closure callable,nullnullfromandtocannot be bothnullboost boolean,integerfalseUsed to adjust the weight of the condition -
Output
self -
Examples
- basic example
// find all users with either active someRelations or red someOtherRelations // Note: the parent 'whereHas' is interchangable with 'where' clause User::es()->whereHas(function($q) { $q->orWhereHas('someRelations', function($k) { $k->where('status', 'active'); })->orWhereHas('someOtherRelations', function($k) { $k->where('color', 'red'); }); })->first();
- basic example
whereHasNull
-
Parameters
Name Required Type Default Description relation Y stringMust be capitalized closure null,callablenull -
Output
self -
Examples
- basic example
// find all users with no someRelation User::es()->whereHasNull('someRelations')->first();
- with sub query
// find all users with no someRelation with id = 1 User::es()->whereHasNull('someRelations', function($q) { $q->where('id', 1); })->first();
- basic example
orWhereHasNull
-
Parameters
Name Required Type Default Description relation Y stringMust be capitalized closure null,callablenull -
Output
self -
Examples
- basic example
// find all users either with no someRelation or named as 'Leo' User::es()->where(function($q) { $q->orWhereHasNull('someRelations')->orWhere('name', 'Leo'); })->first();
- basic example
whereIn
-
Parameters
Name Required Type Default Description column Y stringvalues Y array -
Output
self -
Examples
- basic example
// find all users with pending or active status User::es()->whereIn('status', ['active', 'pending'])->get();
- basic example
orWhereIn
-
Parameters
Name Required Type Default Description column Y stringvalues Y array -
Output
self -
Examples
- basic example
// find all users with either pending/active status or with name Leo User::es()->where(function($q) { $q->orWhereIn('status', ['active', 'pending'])->orWhere('name', 'Leo'); })->get();
- basic example
whereNotIn
-
Parameters
Name Required Type Default Description column Y stringvalues Y array -
Output
self -
Examples
- basic example
// find all users that are not in pending or active status User::es()->whereNotIn('status', ['active', 'pending'])->get();
- basic example
orWhereNotIn
-
Parameters
Name Required Type Default Description column Y stringvalues Y array -
Output
self -
Examples
- basic example
// find all users with either not in pending/active status or with name Leo User::es()->where(function($q) { $q->orWhereNotIn('status', ['active', 'pending'])->orWhere('name', 'Leo'); })->get();
- basic example
whereBetween
-
Parameters
Name Required Type Default Description column Y stringfrom numericnullfromandtocannot be bothnullto numericnull -
Output
self -
Examples
- basic example
User::es()->whereBetween('id', 1, 5)->first()
- basic example
orWhereBetween
-
Parameters
Name Required Type Default Description column Y stringfrom numericnullfromandtocannot be bothnullto numericnull -
Output
self -
Examples
- basic example
User::es()->orWhereBetween('id', 1, 5)->first()
- basic example
Order
orderBy
-
Parameters
Name Required Type Default Description column Y stringorder numericasceither ascordescscript array,booleanfalse -
Output
self -
Examples
- basic example
User::es()->orderBy('id', 'desc')->get()
- script
// If the category of the item is Laptop then use discount_price for ordering. Otherwise, use listing_price. Item::es()->orderBy('id', 'desc', ['lang' => 'painless', 'source' => "if(doc['category'].value == 'Laptops') {return doc['discount_price'].value;} else {return doc['listing_price'].value;}"]) ->get()
- basic example
Pagination
page
-
Parameters
Name Required Type Default Description page Y integerper_page Y integer -
Output
self -
Examples
- basic example
// get the first page. 25 users per page. User::es()->page(1, 25)->get()
- basic example
limit
-
Parameters
Name Required Type Default Description limit Y integer -
Output
self -
Examples
- basic example
// get 25 users. User::es()->limit(25)->get()
- basic example
offset
-
Parameters
Name Required Type Default Description limit Y integer -
Output
self -
Examples
- basic example
// skip first 25 users. User::es()->offset(25)->get()
- basic example
Aggregations
aggregate
-
Parameters
Name Required Type Default Description name Y stringagg Y callable -
Output
self -
Examples
- basic example
Item::es()->aggregate('group_items_by_categories', function($q) { $q->groupBy('category_id'); })->get()->aggregations();
- with filters
// get all active and pending items. But only aggregate on the filtered items that are also red. // Note: aggregate clause is only applied on the filtered items. Item::es()->whereIn('status', ['active', 'pending'])->aggregate('categories', function($q) { $q->where('color', 'red')->aggregate('group_by', function($k) { $k->groupBy('category_id'); }); })->get()->aggregations(); // this returns // [ // 'categories' => [ // 'doc_count' => 50, // 'group_by' => [ // 'doc_count_error_upper_bound' => 0, // 'sum_other_doc_count' => 8, // 'buckets' => [ // [ // 'key' => 1, // 'doc_count' => 15 // ], // ... // ] // ] // ] // ] // the 'key' in buckets is one of the category_id
- basic example
aggregateAll
-
Parameters
Name Required Type Default Description name Y stringagg Y callable -
Output
self -
Examples
- with filters
// get all active and pending items. And aggregate on all red items. // Note: aggregateAll clause is applied on all items regardless other queries. Item::es()->whereIn('status', ['active', 'pending'])->aggregateAll('categories', function($q) { $q->where('color', 'red')->aggregate('group_by', function($k) { $k->groupBy('category_id'); }); })->get()->aggregations(); // this returns // [ // 'categories' => [ // 'doc_count' => 50, // 'group_by' => [ // 'doc_count_error_upper_bound' => 0, // 'sum_other_doc_count' => 8, // 'buckets' => [ // [ // 'key' => 1, // 'doc_count' => 15 // ], // ... // ] // ] // ] // ] // the 'key' in buckets is one of the category_id
- with filters
aggregateOn
-
Parameters
Name Required Type Default Description relation Y stringMust be capitalized agg Y callablecustom_name stringnull -
Output
self -
Examples
- basic example
Item::es()->aggregateOn('someRelations', function($q) { $q->min('id'); })->get()->aggregations(); // this returns // [ // 'some_relations' => [ // 'doc_count' => 50, // 'min_id' => [ // 'value' => 1 // ] // ] // ] // 'some_relations' will be replaced if custom_name is provided
- basic example
groupBy
-
Parameters
Name Required Type Default Description column Y stringsize integer10The limit of number of groups. Default to 10 groups -
Output
self -
Check aggregate clause for examples
min
-
Parameters
Name Required Type Default Description column Y stringcustom_name stringnull -
Output
self -
Examples
- basic example
Item::es()->min('id')->get()->aggregations(); // or Item::es()->aggregate('test', function($q) { $q->min('id'); })->get()->aggregations(); // They both return. Note: the 'test' in the second example is ignored. // [ // 'min_id' => [ // 'value' => 1 // ] // ] // 'min_id' will be replaced if custom_name is provided. The format of the name is 'min_' + column
- basic example
max
-
Parameters
Name Required Type Default Description column Y stringcustom_name stringnullmissing_value numericnullThis value will be used to replace null values -
Output
self -
Examples
- basic example
Item::es()->max('id')->get()->aggregations(); // or Item::es()->aggregate('test', function($q) { $q->max('id'); })->get()->aggregations(); // They both return. Note: the 'test' in the second example is ignored. // [ // 'max_id' => [ // 'value' => 1 // ] // ] // 'min_id' will be replaced if custom_name is provided. The format of the name is 'max_' + column
- basic example
avg
-
Parameters
Name Required Type Default Description column Y stringcustom_name stringnullmissing_value numericnullThis value will be used to replace null values -
Output
self -
Examples
- basic example
Item::es()->avg('id')->get()->aggregations(); // or Item::es()->aggregate('test', function($q) { $q->avg('id'); })->get()->aggregations(); // They both return. Note: the 'test' in the second example is ignored. // [ // 'avg_id' => [ // 'value' => 1 // ] // ] // 'min_id' will be replaced if custom_name is provided. The format of the name is 'avg_' + column
- basic example
sum
-
Parameters
Name Required Type Default Description column stringEmptycustom_name stringnullmissing_value numericnullThis value will be used to replace null values script arraynullCheck official Doc as reference -
Output
self -
Examples
- basic example
Item::es()->sum('id')->get()->aggregations(); // or Item::es()->aggregate('test', function($q) { $q->sum('id'); })->get()->aggregations(); // They both return. Note: the 'test' in the second example is ignored. // [ // 'sum_id' => [ // 'value' => 1 // ] // ] // 'min_id' will be replaced if custom_name is provided. The format of the name is 'sum_' + column
- basic example
Other Filters
minScore
-
Parameters
Name Required Type Default Description score Y numericOnly get items with _score greater than this value -
Output
self -
Examples
- basic example
User::es()->whereMatch('name', 'Leo', ['operator' => 'and'])->minScore(5)->get()
- basic example
with
-
Parameters
Name Required Type Default Description relations Y listinclude these relations in results. All relations are included by default. -
Output
self -
Examples
- basic example
User::es()->with('Addresses', 'Company')->get()
- basic example
withOut
-
Parameters
Name Required Type Default Description relations Y listExclude these relations in results. All relations are included by default. -
Output
self -
Examples
- basic example
User::es()->withOut('Addresses', 'Company')->get()
- basic example
Execute Query
get
scroll
-
Parameters
Name Required Type Default Description scroll_alive string5mThis specifies the life span of the scroll session. scroll_size integer500This specifies the number of records retrieved from Elasticsearch per batch. json booleanfalseIf encode the results from each batch in JSON format. Fetching data and put the data in PHP array can consume a lot of memory. This option can greatly reduce the memory usage. -
Output
array -
Examples
- basic example
User::es()->scroll()
- basic example
count
-
Output
integer -
Examples
- basic example
User::es()->count()
- basic example
first
-
Parameters
Name Required Type Default Description eloquent booleanfalseget result in array or Eloquent. Returns array if not provided. -
Output
array|Eloquent -
Examples
- basic example
User::es()->first()
- basic example
find
-
Parameters
Name Required Type Default Description key Y mixed -
Output
array -
Examples
- basic example
// get the user with id = 5 // Note: the key_name can be set by setKeyName or setOptions. The key_name is 'id' by default User::es()->find(5)
- basic example
delete
-
Delete a record from elasticsearch. Returns false if the record does not exist.
-
Parameters
Name Required Type Default Description key Y mixed -
Output
array -
Examples
- basic example
// delete the user with id = 5 // Note: the key_name can be set by setKeyName or setOptions. The key_name is 'id' by default User::es()->delete(5)
- basic example
Results Manipulation
toArray
-
Output
array
toEloquent
Warning: This function does not work if you don't use the package with Eloquent.
-
Output
Eloquent
rawResults
Get raw results from Elasticsearch
-
Output
array
aggregations
Get aggregation results
-
Output
array
getAggregationBuckets
This is a helper function to get buckets from the aggregation specified by agg_name
-
Parameters
Name Required Type Default Description agg_name Y mixedagg mixednull -
Output
array -
Examples
- basic example
// if the aggregations are // this returns // [ // 'categories' => [ // 'doc_count' => 50, // 'group_by' => [ // 'doc_count_error_upper_bound' => 0, // 'sum_other_doc_count' => 8, // 'buckets' => [ // [ // 'key' => 1, // 'doc_count' => 15 // ], // ... // ] // ] // ] // ] // Then you can use getAggregationBuckets('categories') to get the buckets array
- basic example
paginate
Returns pagination information
-
Parameters
Name Required Type Default Description per_page mixedThe value can be ignored if per_page is set by limit() or page(). Otherwise, it's required. -
Output
array -
Example
- basic
[ "pages" => [ 1, 2, 3, 4, 5, ], "rows" => 165, "active" => 1, "totalpages" => 7.0, "prev" => false, "next" => true, "per_page" => 25 ]
Direct Query Output
getQuery
Returns the query part of the body
getBody
Returns the body
getAggs
Returns the aggregation part of the body
Release History
Meta
Shisun(Leo) Xia - shisun.xia@hotmail.com
Distributed under the GNU V3 license. See LICENSE for more information.
https://github.com/ShisunXia/Laravel-Elasticsearch-Query-Builder