{"id":20531952,"url":"https://github.com/basemkhirat/elasticsearch","last_synced_at":"2025-05-14T10:09:52.872Z","repository":{"id":43675894,"uuid":"78284638","full_name":"basemkhirat/elasticsearch","owner":"basemkhirat","description":"The missing elasticsearch ORM for Laravel, Lumen and Native php applications","archived":false,"fork":false,"pushed_at":"2025-01-14T02:14:23.000Z","size":376,"stargazers_count":403,"open_issues_count":66,"forks_count":128,"subscribers_count":18,"default_branch":"master","last_synced_at":"2025-04-06T05:03:24.319Z","etag":null,"topics":["caching","elasticsearch","eloquent","indexing","laravel","lumen","model","orm","php","query-builder","scout","search-engine"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/basemkhirat.png","metadata":{"files":{"readme":"readme.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-01-07T14:49:32.000Z","updated_at":"2025-04-04T11:48:11.000Z","dependencies_parsed_at":"2024-11-15T14:29:24.826Z","dependency_job_id":"f89f090e-666e-413f-b263-44ecfc9c032e","html_url":"https://github.com/basemkhirat/elasticsearch","commit_stats":{"total_commits":263,"total_committers":16,"mean_commits":16.4375,"dds":"0.11787072243346008","last_synced_commit":"33ea95c730b35a3f29f4ba5c1ea2e2104b3eeb1a"},"previous_names":[],"tags_count":43,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/basemkhirat%2Felasticsearch","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/basemkhirat%2Felasticsearch/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/basemkhirat%2Felasticsearch/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/basemkhirat%2Felasticsearch/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/basemkhirat","download_url":"https://codeload.github.com/basemkhirat/elasticsearch/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248688541,"owners_count":21145763,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["caching","elasticsearch","eloquent","indexing","laravel","lumen","model","orm","php","query-builder","scout","search-engine"],"created_at":"2024-11-16T00:11:23.415Z","updated_at":"2025-04-13T08:51:59.022Z","avatar_url":"https://github.com/basemkhirat.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n\u003c!-- \u003ca href=\"https://travis-ci.org/basemkhirat/elasticsearch\"\u003e\u003cimg src=\"https://travis-ci.org/basemkhirat/elasticsearch.svg?branch=master\" alt=\"Build Status\"\u003e\u003c/a\u003e --\u003e\n\u003ca href=\"https://packagist.org/packages/basemkhirat/elasticsearch\"\u003e\u003cimg src=\"https://poser.pugx.org/basemkhirat/elasticsearch/v/stable.svg\" alt=\"Latest Stable Version\"\u003e\u003c/a\u003e\n\u003ca href=\"https://packagist.org/packages/basemkhirat/elasticsearch\"\u003e\u003cimg src=\"https://poser.pugx.org/basemkhirat/elasticsearch/d/total.svg\" alt=\"Total Downloads\"\u003e\u003c/a\u003e\n\u003ca href=\"https://packagist.org/packages/basemkhirat/elasticsearch\"\u003e\u003cimg src=\"https://poser.pugx.org/basemkhirat/elasticsearch/license.svg\" alt=\"License\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n## Laravel, Lumen and Native php elasticseach query builder to build complex queries using an elegant syntax\n\n- Keeps you away from wasting your time by replacing array queries with a simple and elegant syntax you will love.\n- Elasticsearch data model for types and indices inspired from laravel eloquent.\n- Feeling free to create, drop, mapping and reindexing through easy artisan console commands.\n- Lumen framework support.\n- Native php and composer based applications support.\n- Can be used as a [laravel scout](https://laravel.com/docs/5.4/scout) driver.\n- Dealing with multiple elasticsearch connections at the same time.\n- Awesome pagination based on [LengthAwarePagination](https://github.com/illuminate/pagination).\n- Caching queries using a caching layer over query builder built on [laravel cache](https://laravel.com/docs/5.4/cache).\n\n## Requirements\n\n- `php` \u003e= 5.6.6 \n  \n  See [Travis CI Builds](https://travis-ci.org/basemkhirat/elasticsearch).\n\n- `laravel/laravel` \u003e= 5.* or `laravel/lumen` \u003e= 5.* or `composer application`\n\n\n## Documentation\n\nSee [Full Documentation](https://github.com/basemkhirat/elasticsearch/wiki/1.-Installation).\n\n## Installation\n\n### \u003cu\u003eLaravel Installation\u003c/u\u003e\n\n\n##### 1) Install package using composer.\n\n```bash\n$ composer require basemkhirat/elasticsearch\n```\n\n##### 2) Add package service provider (\u003c laravel 5.5).\n\n```php\nBasemkhirat\\Elasticsearch\\ElasticsearchServiceProvider::class\n```\n\n##### 3) Add package alias (\u003c laravel 5.5).\n\n```php\n'ES' =\u003e Basemkhirat\\Elasticsearch\\Facades\\ES::class\n```\n\t\n##### 4) Publishing.\n\n```bash\n$ php artisan vendor:publish --provider=\"Basemkhirat\\Elasticsearch\\ElasticsearchServiceProvider\"\n```\n\n### \u003cu\u003eLumen Installation\u003c/u\u003e\n\n##### 1) Install package using composer.\n```bash\n$ composer require basemkhirat/elasticsearch\n```\n\n##### 2) Add package service provider in `bootstrap/app.php`.\n\n```php\n$app-\u003eregister(Basemkhirat\\Elasticsearch\\ElasticsearchServiceProvider::class);\n```\n\t\n##### 3) Copy package config directory `vendor/basemkhirat/elasticsearch/src/config` to root folder alongside with `app` directory.\n\t\n\t\n##### 4) Making Lumen work with facades by uncommenting this line in `bootstrap/app.php`.\n\n```php\n$app-\u003ewithFacades();\n```\n\nIf you don't want to enable working with Lumen facades you can access the query builder using `app(\"es\")`.\n\n```php\napp(\"es\")-\u003eindex(\"my_index\")-\u003etype(\"my_type\")-\u003eget();\n\n# is similar to \n\nES::index(\"my_index\")-\u003etype(\"my_type\")-\u003eget();\n```   \n   \n### \u003cu\u003eComposer Installation\u003c/u\u003e\n\nYou can install package with any composer-based applications\n\n##### 1) Install package using composer.\n\n```bash\n$ composer require basemkhirat/elasticsearch\n```\n\n##### 2) Creating a connection.\n\n```php\nrequire \"vendor/autoload.php\";\n\nuse Basemkhirat\\Elasticsearch\\Connection;\n\n$connection = Connection::create([\n    'servers' =\u003e [\n        [\n            \"host\" =\u003e '127.0.0.1',\n            \"port\" =\u003e 9200,\n            'user' =\u003e '',\n            'pass' =\u003e '',\n            'scheme' =\u003e 'http',\n        ],\n    ],\n    \n\t// Custom handlers\n\t// 'handler' =\u003e new MyCustomHandler(),\n\n    'index' =\u003e 'my_index',\n    \n    'logging' =\u003e [\n        'enabled'   =\u003e env('ELASTIC_LOGGING_ENABLED',false),\n        'level'     =\u003e env('ELASTIC_LOGGING_LEVEL','all'),\n        'location'  =\u003e env('ELASTIC_LOGGING_LOCATION',base_path('storage/logs/elasticsearch.log'))\n    ],  \n]);\n\n\n# access the query builder using created connection\n\n$documents = $connection-\u003esearch(\"hello\")-\u003eget();\n```\n\n\n## Configuration (Laravel \u0026 Lumen)\n\n  \nAfter publishing, two configuration files will be created.\n  \n  - `config/es.php` where you can add more than one elasticsearch server.\n\n```php\n# Here you can define the default connection name.\n\n'default' =\u003e env('ELASTIC_CONNECTION', 'default'),\n\n# Here you can define your connections.\n\n'connections' =\u003e [\n\t'default' =\u003e [\n\t    'servers' =\u003e [\n\t        [\n\t            \"host\" =\u003e env(\"ELASTIC_HOST\", \"127.0.0.1\"),\n\t            \"port\" =\u003e env(\"ELASTIC_PORT\", 9200),\n\t            'user' =\u003e env('ELASTIC_USER', ''),\n\t            'pass' =\u003e env('ELASTIC_PASS', ''),\n\t            'scheme' =\u003e env('ELASTIC_SCHEME', 'http'),\n\t        ]\n\t    ],\n\t    \n\t\t// Custom handlers\n\t\t// 'handler' =\u003e new MyCustomHandler(),\n\t\t\n\t\t'index' =\u003e env('ELASTIC_INDEX', 'my_index')\n\t]\n],\n \n# Here you can define your indices.\n \n'indices' =\u003e [\n\t'my_index_1' =\u003e [\n\t    \"aliases\" =\u003e [\n\t        \"my_index\"\n\t    ],\n\t    'settings' =\u003e [\n\t        \"number_of_shards\" =\u003e 1,\n\t        \"number_of_replicas\" =\u003e 0,\n\t    ],\n\t    'mappings' =\u003e [\n\t        'posts' =\u003e [\n                'properties' =\u003e [\n                    'title' =\u003e [\n                        'type' =\u003e 'string'\n                    ]\n                ]\n\t        ]\n\t    ]\n\t]\n]\n\n```\n  \n  - `config/scout.php` where you can use package as a laravel scout driver.\n\n## Working with console environment (Laravel \u0026 Lumen)\n\nWith some artisan commands you can do some tasks such as creating or updating settings, mappings and aliases.\n\nNote that all commands are running with `--connection=default` option, you can change it through the command.\n\nThese are all available commands:\n\n#### List All indices on server\n\n```bash\n$ php artisan es:indices:list\n\n+----------------------+--------+--------+----------+------------------------+-----+-----+------------+--------------+------------+----------------+\n| configured (es.php)  | health | status | index    | uuid                   | pri | rep | docs.count | docs.deleted | store.size | pri.store.size |\n+----------------------+--------+--------+----------+------------------------+-----+-----+------------+--------------+------------+----------------+\n| yes                  | green  | open   | my_index | 5URW60KJQNionAJgL6Q2TQ | 1   | 0   | 0          | 0            | 260b       | 260b           |\n+----------------------+--------+--------+----------+------------------------+-----+-----+------------+--------------+------------+----------------+\n\n```\n\n#### Create indices defined in `es.php` config file\n\nNote that creating operation skips the index if exists.\n\n```bash\n# Create all indices in config file.\n\n$ php artisan es:indices:create\n\n# Create only 'my_index' index in config file\n\n$ php artisan es:indices:create my_index \n\n```\n\n#### Update indices defined in `es.php` config file\n\nNote that updating operation updates indices setting, aliases and mapping and doesn't delete the indexed data.\n\n```bash\n# Update all indices in config file.\n\n$ php artisan es:indices:update\n\n# Update only 'my_index' index in config file\n\n$ php artisan es:indices:update my_index \n\n```\n\n#### Drop index\n\nBe careful when using this command, you will lose your index data!\n\nRunning drop command with `--force` option will skip all confirmation messages.\n\n```bash\n# Drop all indices in config file.\n\n$ php artisan es:indices:drop\n\n# Drop specific index on sever. Not matter for index to be exist in config file or not.\n\n$ php artisan es:indices:drop my_index \n\n```\n\n\n#### Reindexing data (with zero downtime)\n\n##### First, why reindexing?\n\nChanging index mapping doesn't reflect without data reindexing, otherwise your search results will not work on the right way.\n\nTo avoid down time, your application should work with index `alias` not index `name`.\n\nThe index `alias` is a constant name that application should work with to avoid change index names.\n\n##### Assume that we want to change mapping for `my_index`, this is how to do that:\n\n1) Add `alias` as example `my_index_alias` to `my_index` configuration and make sure that application is working with.\n\n```php\n\"aliases\" =\u003e [\n    \"my_index_alias\"\n]       \n```\n\n2) Update index with command:\n\n```bash\n$ php artisan es:indices:update my_index\n```\n\n3) Create a new index as example `my_new_index` with your new mapping in configuration file.\n\n```bash\n$ php artisan es:indices:create my_new_index\n```\n\n4) Reindex data from `my_index` into `my_new_index` with command:\n\n```bash\n$ php artisan es:indices:reindex my_index my_new_index\n\n# Control bulk size. Adjust it with your server.\n\n$ php artisan es:indices:reindex my_index my_new_index --bulk-size=2000\n\n# Control query scroll value.\n\n$ php artisan es:indices:reindex my_index my_new_index --bulk-size=2000 --scroll=2m\n\n# Skip reindexing errors such as mapper parsing exceptions.\n\n$ php artisan es:indices:reindex my_index my_new_index --bulk-size=2000 --skip-errors \n\n# Hide all reindexing errors and show the progres bar only.\n\n$ php artisan es:indices:reindex my_index my_new_index --bulk-size=2000 --skip-errors --hide-errors\n```\n\n5) Remove `my_index_alias` alias from `my_index` and add it to `my_new_index` in configuration file and update with command:\n\n```bash\n$ php artisan es:indices:update\n```\n\n\n## Usage as a Laravel Scout driver\n\nFirst, follow [Laravel Scout installation](https://laravel.com/docs/5.4/scout#installation).\n\nAll you have to do is updating these lines in `config/scout.php` configuration file.\n\n```php\n# change the default driver to 'es'\n\t\n'driver' =\u003e env('SCOUT_DRIVER', 'es'),\n\t\n# link `es` driver with default elasticsearch connection in config/es.php\n\t\n'es' =\u003e [\n    'connection' =\u003e env('ELASTIC_CONNECTION', 'default'),\n],\n```\n\nHave a look at [laravel Scout documentation](https://laravel.com/docs/5.4/scout#configuration).\n\n\n\n## Elasticsearch data model\n\nEach index type has a corresponding \"Model\" which is used to interact with that type.\nModels allow you to query for data in your types or indices, as well as insert new documents into the type.\n\n\n##### Basic usage\n```php\n\u003c?php\n\nnamespace App;\n\nuse Basemkhirat\\Elasticsearch\\Model;\n\nclass Post extends Model\n{\n        \n    protected $type = \"posts\";\n    \n}\n```\n\nThe above example will use the default connection and default index in `es.php`. You can override both in the next example.\n\n```php\n\u003c?php\n\nnamespace App;\n\nuse Basemkhirat\\Elasticsearch\\Model;\n\nclass Post extends Model\n{\n    \n    # [optional] Default: default elasticsearch driver\n    # To override default conenction name of es.php file.\n    # Assumed that there is a connection with name 'my_connection'\n    protected $connection = \"my_connection\";\n    \n    # [optional] Default: default connection index\n    # To override default index name of es.php file.\n    protected $index = \"my_index\";\n    \n    protected $type = \"posts\";\n    \n}\n```\n\n##### Retrieving Models\n\nOnce you have created a model and its associated index type, you are ready to start retrieving data from your index. For example:\n\n\n```php\n\u003c?php\n\nuse App\\Post;\n\n$posts = App\\Post::all();\n\nforeach ($posts as $post) {\n    echo $post-\u003etitle;\n}\n\n```\n\n##### Adding Additional Constraints\n\nThe `all` method will return all of the results in the model's type. Each elasticsearch model serves as a query builder, you may also add constraints to queries, and then use the `get()` method to retrieve the results:\n\n```php\n$posts = App\\Post::where('status', 1)\n               -\u003eorderBy('created_at', 'desc')\n               -\u003etake(10)\n               -\u003eget();\n\n```\n\n\n##### Retrieving Single Models\n\n```php\n// Retrieve a model by document key...\n$posts = App\\Post::find(\"AVp_tCaAoV7YQD3Esfmp\");\n```\n\n\n##### Inserting Models\n\n\nTo create a new document, simply create a new model instance, set attributes on the model, then call the `save()` method:\n\n```php\n\u003c?php\n\nnamespace App\\Http\\Controllers;\n\nuse App\\Post;\nuse Illuminate\\Http\\Request;\nuse App\\Http\\Controllers\\Controller;\n\nclass PostController extends Controller\n{\n    /**\n     * Create a new post instance.\n     *\n     * @param  Request  $request\n     * @return Response\n     */\n    public function store(Request $request)\n    {\n        // Validate the request...\n\n        $post = new Post;\n\n        $post-\u003etitle = $request-\u003etitle;\n\n        $post-\u003esave();\n    }\n}\n```\n\n##### Updating Models\n\nThe `save()` method may also be used to update models that already exist. To update a model, you should retrieve it, set any attributes you wish to update, and then call the save method.\n\n```php\n$post = App\\Post::find(1);\n\n$post-\u003etitle = 'New Post Title';\n\n$post-\u003esave();\n```\n\n##### Deleting Models\n\nTo delete a model, call the `delete()` method on a model instance:\n\n```php\n$post = App\\Post::find(1);\n\n$post-\u003edelete();\n```\n\n##### Query Scopes\n\nScopes allow you to define common sets of constraints that you may easily re-use throughout your application. For example, you may need to frequently retrieve all posts that are considered \"popular\". To define a scope, simply prefix an Eloquent model method with scope.\n\nScopes should always return a Query instance.\n\n```php\n\u003c?php\n\nnamespace App;\n\nuse Basemkhirat\\Elasticsearch\\Model;\n\nclass Post extends Model\n{\n    /**\n     * Scope a query to only include popular posts.\n     *\n     * @param \\Basemkhirat\\Elasticsearch\\Query $query\n     * @return \\Basemkhirat\\Elasticsearch\\Query\n     */\n    public function scopePopular($query, $votes)\n    {\n        return $query-\u003ewhere('votes', '\u003e', $votes);\n    }\n\n    /**\n     * Scope a query to only include active posts.\n     *\n     * @param \\Basemkhirat\\Elasticsearch\\Query $query\n     * @return \\Basemkhirat\\Elasticsearch\\Query\n     */\n    public function scopeActive($query)\n    {\n        return $query-\u003ewhere('active', 1);\n    }\n}\n```\n\nOnce the scope has been defined, you may call the scope methods when querying the model. However, you do not need to include the scope prefix when calling the method. You can even chain calls to various scopes, for example:\n\n```php\n$posts = App\\Post::popular(100)-\u003eactive()-\u003eorderBy('created_at')-\u003eget();\n```\n\n\n##### Accessors \u0026 Mutators\n\n###### Defining An Accessor\nTo define an `accessor`, create a getFooAttribute method on your model where `Foo` is the \"studly\" cased name of the column you wish to access. In this example, we'll define an accessor for the `title` attribute. The accessor will automatically be called by model when attempting to retrieve the value of the `title` attribute:\n\n\n```php\n\u003c?php\n\nnamespace App;\n\nuse Basemkhirat\\Elasticsearch\\Model;\n\nclass post extends Model\n{\n    /**\n     * Get the post title.\n     *\n     * @param  string  $value\n     * @return string\n     */\n    public function getTitleAttribute($value)\n    {\n        return ucfirst($value);\n    }\n}\n```\n\nAs you can see, the original value of the column is passed to the accessor, allowing you to manipulate and return the value. To access the value of the accessor, you may simply access the `title` attribute on a model instance:\n\n```php\n$post = App\\Post::find(1);\n\n$title = $post-\u003etitle;\n```\n\nOccasionally, you may need to add array attributes that do not have a corresponding field in your index. To do so, simply define an accessor for the value:\n\n```php\npublic function getIsPublishedAttribute()\n{\n    return $this-\u003eattributes['status'] == 1;\n}\n```\n\nOnce you have created the accessor, just add the value to the `appends` property on the model:\n\n```php\nprotected $appends = ['is_published'];\n```\n\nOnce the attribute has been added to the appends list, it will be included in model's array.\n\n###### Defining A Mutator\n\nTo define a mutator, define a `setFooAttribute` method on your model where `Foo` is the \"studly\" cased name of the column you wish to access. So, again, let's define a mutator for the `title` attribute. This mutator will be automatically called when we attempt to set the value of the `title`attribute on the model:\n\n```php\n\u003c?php\n\nnamespace App;\n\nuse Basemkhirat\\Elasticsearch\\Model;\n\nclass post extends Model\n{\n    /**\n     * Set the post title.\n     *\n     * @param  string  $value\n     * @return void\n     */\n    public function setTitleAttribute($value)\n    {\n        return strtolower($value);\n    }\n}\n```\n\nThe mutator will receive the value that is being set on the attribute, allowing you to manipulate the value and set the manipulated value on the model's internal `$attributes` property. So, for example, if we attempt to set the title attribute to `Awesome post to read`:\n\n```php\n$post = App\\Post::find(1);\n\n$post-\u003etitle = 'Awesome post to read';\n```\n\nIn this example, the setTitleAttribute function will be called with the value `Awesome post to read`. The mutator will then apply the strtolower function to the name and set its resulting value in the internal $attributes array.\n\n\n\n##### Attribute Casting\n\n\nThe `$casts` property on your model provides a convenient method of converting attributes to common data types. The `$casts` property should be an array where the key is the name of the attribute being cast and the value is the type you wish to cast the column to. The supported cast types are: `integer`, `float`, `double`, `string`, `boolean`, `object` and `array`.\n\n\nFor example, let's cast the `is_published` attribute, which is stored in our index as an integer (0 or  1) to a `boolean` value:\n\n```php\n\u003c?php\n\nnamespace App;\n\nuse Basemkhirat\\Elasticsearch\\Model;\n\nclass Post extends Model\n{\n    /**\n     * The attributes that should be cast to native types.\n     *\n     * @var array\n     */\n    protected $casts = [\n        'is_published' =\u003e 'boolean',\n    ];\n}\n\n```\n\nNow the `is_published` attribute will always be cast to a `boolean` when you access it, even if the underlying value is stored in the index as an integer:\n\n\n```php\n$post = App\\Post::find(1);\n\nif ($post-\u003eis_published) {\n    //\n}\n```\n\n\n\n## Usage as a query builder\n\n#### Creating a new index\n\n```php\nES::create(\"my_index\");\n    \n# or \n    \nES::index(\"my_index\")-\u003ecreate();\n```\n    \n##### Creating index with custom options (optional)\n   \n```php\nES::index(\"my_index\")-\u003ecreate(function($index){\n        \n    $index-\u003eshards(5)-\u003ereplicas(1)-\u003emapping([\n        'my_type' =\u003e [\n            'properties' =\u003e [\n                'first_name' =\u003e [\n                    'type' =\u003e 'string',\n                ],\n                'age' =\u003e [\n                    'type' =\u003e 'integer'\n                ]\n            ]\n        ]\n    ])\n    \n});\n    \n# or\n    \nES::create(\"my_index\", function($index){\n  \n      $index-\u003eshards(5)-\u003ereplicas(1)-\u003emapping([\n          'my_type' =\u003e [\n              'properties' =\u003e [\n                  'first_name' =\u003e [\n                      'type' =\u003e 'string',\n                  ],\n                  'age' =\u003e [\n                      'type' =\u003e 'integer'\n                  ]\n              ]\n          ]\n      ])\n  \n});\n\n```\n#### Dropping index\n\n```php\nES::drop(\"my_index\");\n    \n# or\n    \nES::index(\"my_index\")-\u003edrop();\n```\n#### Running queries\n```php\n$documents = ES::connection(\"default\")\n                -\u003eindex(\"my_index\")\n                -\u003etype(\"my_type\")\n                -\u003eget();    # return a collection of results\n```\nYou can rewrite the above query to\n\n```php\n$documents = ES::type(\"my_type\")-\u003eget();    # return a collection of results\n```\n\nThe query builder will use the default connection, index name in configuration file `es.php`. \n \nConnection and index names in query overrides connection and index names in configuration file `es.php`.\n\n##### Getting document by id\n```php\nES::type(\"my_type\")-\u003eid(3)-\u003efirst();\n    \n# or\n    \nES::type(\"my_type\")-\u003e_id(3)-\u003efirst();\n```\n##### Sorting\n```php \nES::type(\"my_type\")-\u003eorderBy(\"created_at\", \"desc\")-\u003eget();\n    \n# Sorting with text search score\n    \nES::type(\"my_type\")-\u003eorderBy(\"_score\")-\u003eget();\n```\n##### Limit and offset\n```php\nES::type(\"my_type\")-\u003etake(10)-\u003eskip(5)-\u003eget();\n```\n##### Select only specific fields\n```php    \nES::type(\"my_type\")-\u003eselect(\"title\", \"content\")-\u003etake(10)-\u003eskip(5)-\u003eget();\n```\n##### Where clause\n```php    \nES::type(\"my_type\")-\u003ewhere(\"status\", \"published\")-\u003eget();\n\n# or\n\nES::type(\"my_type\")-\u003ewhere(\"status\", \"=\", \"published\")-\u003eget();\n```\n##### Where greater than\n```php\nES::type(\"my_type\")-\u003ewhere(\"views\", \"\u003e\", 150)-\u003eget();\n```\n##### Where greater than or equal\n```php\nES::type(\"my_type\")-\u003ewhere(\"views\", \"\u003e=\", 150)-\u003eget();\n```\n##### Where less than\n```php\nES::type(\"my_type\")-\u003ewhere(\"views\", \"\u003c\", 150)-\u003eget();\n```\n##### Where less than or equal\n```php\nES::type(\"my_type\")-\u003ewhere(\"views\", \"\u003c=\", 150)-\u003eget();\n```\n##### Where like\n```php\nES::type(\"my_type\")-\u003ewhere(\"title\", \"like\", \"foo\")-\u003eget();\n```\n##### Where field exists\n```php\nES::type(\"my_type\")-\u003ewhere(\"hobbies\", \"exists\", true)-\u003eget(); \n\n# or \n\nES::type(\"my_type\")-\u003ewhereExists(\"hobbies\", true)-\u003eget();\n```    \n##### Where in clause\n```php    \nES::type(\"my_type\")-\u003ewhereIn(\"id\", [100, 150])-\u003eget();\n```\n##### Where between clause \n```php    \nES::type(\"my_type\")-\u003ewhereBetween(\"id\", 100, 150)-\u003eget();\n\n# or \n\nES::type(\"my_type\")-\u003ewhereBetween(\"id\", [100, 150])-\u003eget();\n```    \n##### Where not clause\n```php    \nES::type(\"my_type\")-\u003ewhereNot(\"status\", \"published\")-\u003eget(); \n\n# or\n\nES::type(\"my_type\")-\u003ewhereNot(\"status\", \"=\", \"published\")-\u003eget();\n```\n##### Where not greater than\n```php\nES::type(\"my_type\")-\u003ewhereNot(\"views\", \"\u003e\", 150)-\u003eget();\n```\n##### Where not greater than or equal\n```php\nES::type(\"my_type\")-\u003ewhereNot(\"views\", \"\u003e=\", 150)-\u003eget();\n```\n##### Where not less than\n```php\nES::type(\"my_type\")-\u003ewhereNot(\"views\", \"\u003c\", 150)-\u003eget();\n```\n##### Where not less than or equal\n```php\nES::type(\"my_type\")-\u003ewhereNot(\"views\", \"\u003c=\", 150)-\u003eget();\n```\n##### Where not like\n```php\nES::type(\"my_type\")-\u003ewhereNot(\"title\", \"like\", \"foo\")-\u003eget();\n```\n##### Where not field exists\n```php\nES::type(\"my_type\")-\u003ewhereNot(\"hobbies\", \"exists\", true)-\u003eget(); \n\n# or\n\nES::type(\"my_type\")-\u003ewhereExists(\"hobbies\", true)-\u003eget();\n```    \n##### Where not in clause\n```php    \nES::type(\"my_type\")-\u003ewhereNotIn(\"id\", [100, 150])-\u003eget();\n```\n##### Where not between clause \n```php    \nES::type(\"my_type\")-\u003ewhereNotBetween(\"id\", 100, 150)-\u003eget();\n\n# or\n\nES::type(\"my_type\")-\u003ewhereNotBetween(\"id\", [100, 150])-\u003eget();\n```\n   \n##### Search by a distance from a geo point \n```php  \nES::type(\"my_type\")-\u003edistance(\"location\", [\"lat\" =\u003e -33.8688197, \"lon\" =\u003e 151.20929550000005], \"10km\")-\u003eget();\n\n# or\n\nES::type(\"my_type\")-\u003edistance(\"location\", \"-33.8688197,151.20929550000005\", \"10km\")-\u003eget();\n\n# or\n\nES::type(\"my_type\")-\u003edistance(\"location\", [151.20929550000005, -33.8688197], \"10km\")-\u003eget();  \n```\n  \n  \n##### Search using array queries\n      \n```php\nES::type(\"my_type\")-\u003ebody([\n    \"query\" =\u003e [\n         \"bool\" =\u003e [\n             \"must\" =\u003e [\n                 [ \"match\" =\u003e [ \"address\" =\u003e \"mill\" ] ],\n                 [ \"match\" =\u003e [ \"address\" =\u003e \"lane\" ] ]\n             ]\n         ]\n     ]\n])-\u003eget();\n\n# Note that you can mix between query builder and array queries.\n# The query builder will will be merged with the array query.\n\nES::type(\"my_type\")-\u003ebody([\n\n\t\"_source\" =\u003e [\"content\"]\n\t\n\t\"query\" =\u003e [\n\t     \"bool\" =\u003e [\n\t         \"must\" =\u003e [\n\t             [ \"match\" =\u003e [ \"address\" =\u003e \"mill\" ] ]\n\t         ]\n\t     ]\n\t],\n\t   \n\t\"sort\" =\u003e [\n\t\t\"_score\"\n\t]\n     \n])-\u003eselect(\"name\")-\u003eorderBy(\"created_at\", \"desc\")-\u003etake(10)-\u003eskip(5)-\u003eget();\n\n# The result query will be\n/*\nArray\n(\n    [index] =\u003e my_index\n    [type] =\u003e my_type\n    [body] =\u003e Array\n        (\n            [_source] =\u003e Array\n                (\n                    [0] =\u003e content\n                    [1] =\u003e name\n                )\n            [query] =\u003e Array\n                (\n                    [bool] =\u003e Array\n                        (\n                            [must] =\u003e Array\n                                (\n                                    [0] =\u003e Array\n                                        (\n                                            [match] =\u003e Array\n                                                (\n                                                    [address] =\u003e mill\n                                                )\n                                        )\n                                )\n                        )\n                )\n            [sort] =\u003e Array\n                (\n                    [0] =\u003e _score\n                    [1] =\u003e Array\n                        (\n                            [created_at] =\u003e desc\n                        )\n                )\n        )\n    [from] =\u003e 5\n    [size] =\u003e 10\n    [client] =\u003e Array\n        (\n            [ignore] =\u003e Array\n                (\n                )\n        )\n)\n*/\n\n```\n  \n##### Search the entire document\n    \n```php\nES::type(\"my_type\")-\u003esearch(\"hello\")-\u003eget();\n    \n# search with Boost = 2\n    \nES::type(\"my_type\")-\u003esearch(\"hello\", 2)-\u003eget();\n\n# search within specific fields with different weights\n\nES::type(\"my_type\")-\u003esearch(\"hello\", function($search){\n\t$search-\u003eboost(2)-\u003efields([\"title\" =\u003e 2, \"content\" =\u003e 1])\n})-\u003eget();\n```\n\n##### Search with highlight fields\n    \n```php\n$doc = ES::type(\"my_type\")-\u003ehighlight(\"title\")-\u003esearch(\"hello\")-\u003efirst();\n\n# Multiple fields Highlighting is allowed.\n\n$doc = ES::type(\"my_type\")-\u003ehighlight(\"title\", \"content\")-\u003esearch(\"hello\")-\u003efirst();\n\n# Return all highlights as array using $doc-\u003egetHighlights() method.\n\n$doc-\u003egetHighlights();\n\n# Also you can return only highlights of specific field.\n\n$doc-\u003egetHighlights(\"title\");\n```\n\n\n##### Return only first record\n\n```php    \nES::type(\"my_type\")-\u003esearch(\"hello\")-\u003efirst();\n```\n  \n##### Return only count\n```php    \nES::type(\"my_type\")-\u003esearch(\"hello\")-\u003ecount();\n```\n    \n##### Scan-and-Scroll queries\n    \n\n\n```php\n# These queries are suitable for large amount of data. \n# A scrolled search allows you to do an initial search and to keep pulling batches of results\n# from Elasticsearch until there are no more results left.\n# It’s a bit like a cursor in a traditional database\n    \n$documents = ES::type(\"my_type\")-\u003esearch(\"hello\")\n                 -\u003escroll(\"2m\")\n                 -\u003etake(1000)\n                 -\u003eget();\n\n# Response will contain a hashed code `scroll_id` will be used to get the next result by running\n\n$documents = ES::type(\"my_type\")-\u003esearch(\"hello\")\n                 -\u003escroll(\"2m\")\n                 -\u003escrollID(\"DnF1ZXJ5VGhlbkZldGNoBQAAAAAAAAFMFlJQOEtTdnJIUklhcU1FX2VqS0EwZncAAAAAAAABSxZSUDhLU3ZySFJJYXFNRV9laktBMGZ3AAAAAAAAAU4WUlA4S1N2ckhSSWFxTUVfZWpLQTBmdwAAAAAAAAFPFlJQOEtTdnJIUklhcU1FX2VqS0EwZncAAAAAAAABTRZSUDhLU3ZySFJJYXFNRV9laktBMGZ3\")\n                 -\u003eget();\n\n# And so on ...\n# Note that you don't need to write the query parameters in every scroll. All you need the `scroll_id` and query scroll time.\n    \n# To clear `scroll_id` \n  \nES::type(\"my_type\")-\u003escrollID(\"DnF1ZXJ5VGhlbkZldGNoBQAAAAAAAAFMFlJQOEtTdnJIUklhcU1FX2VqS0EwZncAAAAAAAABSxZSUDhLU3ZySFJJYXFNRV9laktBMGZ3AAAAAAAAAU4WUlA4S1N2ckhSSWFxTUVfZWpLQTBmdwAAAAAAAAFPFlJQOEtTdnJIUklhcU1FX2VqS0EwZncAAAAAAAABTRZSUDhLU3ZySFJJYXFNRV9laktBMGZ3\")\n        -\u003eclear();\n```\n    \n##### Paginate results with 5 records per page\n\n```php   \n$documents = ES::type(\"my_type\")-\u003esearch(\"hello\")-\u003epaginate(5);\n    \n# Getting pagination links\n    \n$documents-\u003elinks();\n\n# Bootstrap 4 pagination\n\n$documents-\u003elinks(\"bootstrap-4\");\n\n# Simple bootstrap 4 pagination\n\n$documents-\u003elinks(\"simple-bootstrap-4\");\n\n# Simple pagination\n\n$documents-\u003elinks(\"simple-default\");\n```\n\nThese are all pagination methods you may use:\n\n```php\n$documents-\u003ecount()\n$documents-\u003ecurrentPage()\n$documents-\u003efirstItem()\n$documents-\u003ehasMorePages()\n$documents-\u003elastItem()\n$documents-\u003elastPage()\n$documents-\u003enextPageUrl()\n$documents-\u003eperPage()\n$documents-\u003epreviousPageUrl()\n$documents-\u003etotal()\n$documents-\u003eurl($page)\n```\n\n##### Getting the query array without execution\n\n```php\nES::type(\"my_type\")-\u003esearch(\"hello\")-\u003ewhere(\"views\", \"\u003e\", 150)-\u003equery();\n```\n\n##### Getting the original elasticsearch response\n\n```php\nES::type(\"my_type\")-\u003esearch(\"hello\")-\u003ewhere(\"views\", \"\u003e\", 150)-\u003eresponse();\n```\n\n##### Ignoring bad HTTP response\n\n```php      \nES::type(\"my_type\")-\u003eignore(404, 500)-\u003eid(5)-\u003efirst();\n```\n\n##### Query Caching (Laravel \u0026 Lumen)\n\nPackage comes with a built-in caching layer based on laravel cache.\n\n```php\nES::type(\"my_type\")-\u003esearch(\"hello\")-\u003eremember(10)-\u003eget();\n\t\n# Specify a custom cache key\n\nES::type(\"my_type\")-\u003esearch(\"hello\")-\u003eremember(10, \"last_documents\")-\u003eget();\n\t\n# Caching using other available driver\n\t\nES::type(\"my_type\")-\u003esearch(\"hello\")-\u003ecacheDriver(\"redis\")-\u003eremember(10, \"last_documents\")-\u003eget();\n\t\n# Caching with cache key prefix\n\t\nES::type(\"my_type\")-\u003esearch(\"hello\")-\u003ecacheDriver(\"redis\")-\u003ecachePrefix(\"docs\")-\u003eremember(10, \"last_documents\")-\u003eget();\n```\n\n##### Executing elasticsearch raw queries\n\n```php\nES::raw()-\u003esearch([\n    \"index\" =\u003e \"my_index\",\n    \"type\"  =\u003e \"my_type\",\n    \"body\" =\u003e [\n        \"query\" =\u003e [\n            \"bool\" =\u003e [\n                \"must\" =\u003e [\n                    [ \"match\" =\u003e [ \"address\" =\u003e \"mill\" ] ],\n                    [ \"match\" =\u003e [ \"address\" =\u003e \"lane\" ] ]\n                ]\n            ]\n        ]\n    ]\n]);\n```\n   \n##### Insert a new document\n    \n```php\nES::type(\"my_type\")-\u003eid(3)-\u003einsert([\n    \"title\" =\u003e \"Test document\",\n    \"content\" =\u003e \"Sample content\"\n]);\n     \n# A new document will be inserted with _id = 3.\n  \n# [id is optional] if not specified, a unique hash key will be generated.\n```\n  \u003e\n    \n##### Bulk insert a multiple of documents at once.\n     \n```php\n# Main query\n\nES::index(\"my_index\")-\u003etype(\"my_type\")-\u003ebulk(function ($bulk){\n\n    # Sub queries\n\n\t$bulk-\u003eindex(\"my_index_1\")-\u003etype(\"my_type_1\")-\u003eid(10)-\u003einsert([\"title\" =\u003e \"Test document 1\",\"content\" =\u003e \"Sample content 1\"]);\n\t$bulk-\u003eindex(\"my_index_2\")-\u003eid(11)-\u003einsert([\"title\" =\u003e \"Test document 2\",\"content\" =\u003e \"Sample content 2\"]);\n\t$bulk-\u003eid(12)-\u003einsert([\"title\" =\u003e \"Test document 3\", \"content\" =\u003e \"Sample content 3\"]);\n\t\n});\n\n# Notes from the above query:\n\n# As index and type names are required for insertion, Index and type names are extendable. This means that: \n\n# If index() is not specified in subquery:\n# -- The builder will get index name from the main query.\n# -- if index is not specified in main query, the builder will get index name from configuration file.\n\n# And\n\n# If type() is not specified in subquery:\n# -- The builder will get type name from the main query.\n\n# you can use old bulk code style using multidimensional array of [id =\u003e data] pairs\n \nES::type(\"my_type\")-\u003ebulk([\n \n\t10 =\u003e [\n\t\t\"title\" =\u003e \"Test document 1\",\n\t\t\"content\" =\u003e \"Sample content 1\"\n\t],\n\t \n\t11 =\u003e [\n\t\t\"title\" =\u003e \"Test document 2\",\n\t\t\"content\" =\u003e \"Sample content 2\"\n\t]\n \n]);\n \n# The two given documents will be inserted with its associated ids\n```\n\n##### Update an existing document\n```php     \nES::type(\"my_type\")-\u003eid(3)-\u003eupdate([\n   \"title\" =\u003e \"Test document\",\n   \"content\" =\u003e \"sample content\"\n]);\n    \n# Document has _id = 3 will be updated.\n    \n# [id is required]\n```\n\n```php\n# Bulk update\n\nES::type(\"my_type\")-\u003ebulk(function ($bulk){\n    $bulk-\u003eid(10)-\u003eupdate([\"title\" =\u003e \"Test document 1\",\"content\" =\u003e \"Sample content 1\"]);\n    $bulk-\u003eid(11)-\u003eupdate([\"title\" =\u003e \"Test document 2\",\"content\" =\u003e \"Sample content 2\"]);\n});\n```\n   \n##### Incrementing field\n```php\nES::type(\"my_type\")-\u003eid(3)-\u003eincrement(\"views\");\n    \n# Document has _id = 3 will be incremented by 1.\n    \nES::type(\"my_type\")-\u003eid(3)-\u003eincrement(\"views\", 3);\n    \n# Document has _id = 3 will be incremented by 3.\n\n# [id is required]\n```\n   \n##### Decrementing field\n```php \nES::type(\"my_type\")-\u003eid(3)-\u003edecrement(\"views\");\n    \n# Document has _id = 3 will be decremented by 1.\n    \nES::type(\"my_type\")-\u003eid(3)-\u003edecrement(\"views\", 3);\n    \n# Document has _id = 3 will be decremented by 3.\n\n# [id is required]\n```\n   \n##### Update using script\n       \n```php\n# increment field by script\n    \nES::type(\"my_type\")-\u003eid(3)-\u003escript(\n    \"ctx._source.$field += params.count\",\n    [\"count\" =\u003e 1]\n);\n    \n# add php tag to tags array list\n    \nES::type(\"my_type\")-\u003eid(3)-\u003escript(\n    \"ctx._source.tags.add(params.tag)\",\n    [\"tag\" =\u003e \"php\"]\n);\n    \n# delete the doc if the tags field contain mongodb, otherwise it does nothing (noop)\n    \nES::type(\"my_type\")-\u003eid(3)-\u003escript(\n    \"if (ctx._source.tags.contains(params.tag)) { ctx.op = 'delete' } else { ctx.op = 'none' }\",\n    [\"tag\" =\u003e \"mongodb\"]\n);\n```\n   \n##### Delete a document\n```php\nES::type(\"my_type\")-\u003eid(3)-\u003edelete();\n    \n# Document has _id = 3 will be deleted.\n    \n# [id is required]\n```\n\n```php\n# Bulk delete\n\nES::type(\"my_type\")-\u003ebulk(function ($bulk){\n    $bulk-\u003eid(10)-\u003edelete();\n    $bulk-\u003eid(11)-\u003edelete();\n});\n```\n\n## Releases\n\n  See [Change Log](https://github.com/basemkhirat/elasticsearch/blob/master/CHANGELOG.md).\n\n## Author\n[Basem Khirat](http://basemkhirat.com) - [basemkhirat@gmail.com](mailto:basemkhirat@gmail.com) - [@basemkhirat](https://twitter.com/basemkhirat)  \n\n\n## Bugs, Suggestions and Contributions\n\nThanks to [everyone](https://github.com/basemkhirat/elasticsearch/graphs/contributors)\nwho has contributed to this project!\n\nPlease use [Github](https://github.com/basemkhirat/elasticsearch) for reporting bugs, \nand making comments or suggestions.\n\n## License\n\nMIT\n\n`Have a happy searching..`\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbasemkhirat%2Felasticsearch","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbasemkhirat%2Felasticsearch","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbasemkhirat%2Felasticsearch/lists"}