# Elasticsearch Support ## Overview Elasticsearch is a distributed RESTful search and analytics engine capable of solving a growing number of use cases: application search, security analytics, metrics, logging, etc. API Platform comes natively with the **reading** support for Elasticsearch. It uses internally the official PHP client for Elasticsearch: [Elasticsearch-PHP](https://www.elastic.co/guide/en/elasticsearch/client/php-api/current/index.html). Be careful, API Platform only supports Elasticsearch >= 7.11.0 < 8.0 and Elasticsearch >= 8.4 < 9.0. Support for Elasticsearch 8 was introduced in API Platform 3.2. ## Enabling Reading Support To enable the reading support for Elasticsearch, simply require the Elasticsearch-PHP package using Composer. For Elasticsearch 8: ```console composer require elasticsearch/elasticsearch:^8.4 ``` For Elasticsearch 7: ```console composer require elasticsearch/elasticsearch:^7.11 ``` Then, enable it inside the API Platform configuration, using one of the configurations below: ### Enabling Reading Support using Symfony ```yaml # api/config/packages/api_platform.yaml parameters: # ... env(ELASTICSEARCH_HOST): 'http://localhost:9200' api_platform: # ... mapping: paths: ['%kernel.project_dir%/src/Model'] elasticsearch: hosts: ['%env(ELASTICSEARCH_HOST)%'] #... ``` ### Enabling Reading Support using Laravel ```php [ 'paths' => [ base_path('app/Models'), ], ], 'elasticsearch' => [ 'hosts' => [ env('ELASTICSEARCH_HOST', 'http://localhost:9200'), ], ], ]; ``` ## Creating Models API Platform follows the best practices of Elasticsearch: - a single index per resource should be used because Elasticsearch is going to [drop support for index types and will allow only a single type per index](https://www.elastic.co/guide/en/elasticsearch/reference/current/removal-of-types.html); - index name should be the short resource name in lower snake_case; - the default `_doc` type should be used; - all fields should be lower case and should use camelCase for combining words. This involves having mappings and models which absolutely match each other. Here is an example of mappings for 2 resources, `User` and `Tweet`, and their models: `PUT user` ```json { "mappings": { "_doc": { "properties": { "id": { "type": "keyword" }, "gender": { "type": "keyword" }, "age": { "type": "integer" }, "first_name": { "type": "text" }, "last_name": { "type": "text" }, "tweets": { "type": "nested", "properties": { "id": { "type": "keyword" }, "date": { "type": "date", "format": "yyyy-MM-dd HH:mm:ss" }, "message": { "type": "text" } }, "dynamic": "strict" } }, "dynamic": "strict" } } } ``` `PUT tweet` ```json { "mappings": { "_doc": { "properties": { "id": { "type": "keyword" }, "author": { "properties": { "id": { "type": "keyword" }, "gender": { "type": "keyword" }, "age": { "type": "integer" }, "first_name": { "type": "text" }, "last_name": { "type": "text" } }, "dynamic": "strict" }, "date": { "type": "date", "format": "yyyy-MM-dd HH:mm:ss" }, "message": { "type": "text" } }, "dynamic": "strict" } } } ``` ```php