georgebohnisch / laravel-elasticsearch-query-builder
:Query Elasticsearch by using Eloquent
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: 2024-11-08 07:38:34 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.json
file:"shisun/laravel-elasticsearch-query-builder": "dev-master"
-
Run
composer update
in terminal -
Add the package to your
app.php
file in the config folder:'providers' => [ ... Shisun\LaravelElasticsearchQueryBuilder\LaravelElasticsearchQueryBuilderServiceProvider::class, ]
-
If your Elasticsearch is not accessible at
localhost:9200
then you have to publish the config file by running:$ php artisan vendor:publish --provider="Shisun\LaravelElasticsearchQueryBuilder\LaravelElasticsearchQueryBuilderServiceProvider"
-
(Optional) Change the
ES_HOSTS
in config/laravel-elasticsearch-query-builder.php to the address of your Elasticsearch -
Use with Eloquent Model
- Add
EsTrait
to 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
-
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
-
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
-
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()
column
can be a functionUser::es()->where(function($q) { $q->orWhere(...)->orWhere(...); })->get()->toArray()
whereNull
-
Parameters
-
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
-
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
-
Output
self
-
Examples
=
can be ignoredUser::es()->orWhere('id', 1)->first()
column
can 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
-
Output
self
-
Examples
- without
options
User::es()->whereMatch('email', 'shisun@')->first()
- with
options
User::es()->whereMatch('email', 'shisun@', [ 'query' => 'this will be overrided by $value', 'operator' => 'and', 'zero_terms_query' => 'all' ])->first()
- without
whereDoesntMatch
-
Parameters
-
Output
self
-
Examples
- without
options
User::es()->whereDoesntMatch('email', 'shisun@')->first()
- with
options
User::es()->whereDoesntMatch('email', 'shisun@', [ 'query' => 'this will be overrided by $value', 'operator' => 'and', 'zero_terms_query' => 'all' ])->first()
- without
orWhereMatch
-
Parameters
-
Output
self
-
Examples
- without
options
User::es()->orWhereMatch('email', 'shisun@')->first()
- with
options
User::es()->orWhereMatch('email', 'shisun@', [ 'query' => 'this will be overrided by $value', 'operator' => 'and', 'zero_terms_query' => 'all' ])->first()
- without
whereHas
-
Parameters
-
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
-
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
-
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
-
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
-
Output
self
-
Examples
- basic example
// find all users with pending or active status User::es()->whereIn('status', ['active', 'pending'])->get();
- basic example
orWhereIn
-
Parameters
-
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
-
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
-
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
-
Output
self
-
Examples
- basic example
User::es()->whereBetween('id', 1, 5)->first()
- basic example
orWhereBetween
-
Parameters
-
Output
self
-
Examples
- basic example
User::es()->orWhereBetween('id', 1, 5)->first()
- basic example
Order
orderBy
-
Parameters
-
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
-
Output
self
-
Examples
- basic example
// get the first page. 25 users per page. User::es()->page(1, 25)->get()
- basic example
limit
-
Parameters
-
Output
self
-
Examples
- basic example
// get 25 users. User::es()->limit(25)->get()
- basic example
offset
-
Parameters
-
Output
self
-
Examples
- basic example
// skip first 25 users. User::es()->offset(25)->get()
- basic example
Aggregations
aggregate
-
Parameters
-
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
-
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
-
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
-
Output
self
-
Check aggregate clause for examples
min
-
Parameters
-
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
-
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
-
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
-
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
-
Output
self
-
Examples
- basic example
User::es()->whereMatch('name', 'Leo', ['operator' => 'and'])->minScore(5)->get()
- basic example
with
-
Parameters
-
Output
self
-
Examples
- basic example
User::es()->with('Addresses', 'Company')->get()
- basic example
withOut
-
Parameters
-
Output
self
-
Examples
- basic example
User::es()->withOut('Addresses', 'Company')->get()
- basic example
Execute Query
get
scroll
-
Parameters
-
Output
array
-
Examples
- basic example
User::es()->scroll()
- basic example
count
-
Output
integer
-
Examples
- basic example
User::es()->count()
- basic example
first
-
Parameters
-
Output
array
|Eloquent
-
Examples
- basic example
User::es()->first()
- basic example
find
-
Parameters
-
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
-
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
-
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
-
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