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.

Elasticsearch は、アプリケーション検索、セキュリティ分析、メトリクス、ロギングなど、ますます多くのユース ケースを解決できる分散型 RESTful 検索および分析エンジンです。

API Platform comes natively with the reading support for Elasticsearch. It uses internally the official PHP client for Elasticsearch: Elasticsearch-PHP.

API プラットフォームには、Elasticsearch の読み取りサポートがネイティブに付属しています。 Elasticsearch の公式 PHP クライアントである Elasticsearch-PHP を内部的に使用します。

Be careful, API Platform only supports Elasticsearch >= 6.5.0.

API プラットフォームは Elasticsearch >= 6.5.0 のみをサポートすることに注意してください。

Enabling Reading Support

To enable the reading support for Elasticsearch, simply require the Elasticsearch-PHP package using Composer:

Elasticsearch の読み取りサポートを有効にするには、Composer を使用して Elasticsearch-PHP パッケージを要求するだけです。

composer require elasticsearch/elasticsearch:^6.0

Then, enable it inside the API Platform configuration:

次に、API プラットフォーム構成内で有効にします。

# 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)%']

    #...

Creating Models

API Platform follows the best practices of Elasticsearch:

API プラットフォームは、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;
    リソースごとに 1 つのインデックスを使用する必要があります。これは、Elasticsearch がインデックス タイプのサポートを終了し、インデックスごとに 1 つのタイプのみを許可するためです。
  • index name should be the short resource name in lower snake case;
    インデックス名は、小文字のスネーク ケースの短いリソース名にする必要があります。
  • the default _doc type should be used;
    デフォルトの _doc タイプを使用する必要があります。
  • all fields should be lower case and should use camel case 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:

User と Tweet の 2 つのリソースとそれらのモデルのマッピングの例を次に示します。

PUT user

PUT ユーザー

{
  "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

つぶやく

{
  "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
// api/src/Model/User.php
namespace App\Model;

use ApiPlatform\Metadata\ApiProperty;
use ApiPlatform\Metadata\ApiResource;

#[ApiResource]
class User
{
    #[ApiProperty(identifier: true)]
    public string $id = '';

    public string $gender;

    public int $age;

    public string $firstName;

    public string $lastName;

    /**
     * @var Tweet[]
     */
    public iterable $tweets = [];
}
<?php
// api/src/Model/Tweet.php
namespace App\Model;

use ApiPlatform\Metadata\ApiProperty;
use ApiPlatform\Metadata\ApiResource;

 #[ApiResource]
class Tweet
{
    #[ApiProperty(identifier: true)]
    public string $id = '';

    public User $author;

    public \DateTimeInterface $date;

    public string $message;
}

API Platform will automatically disable write operations and snake case document fields will automatically be converted to camel case object properties during serialization.

API プラットフォームは、書き込み操作を自動的に無効にし、スネーク ケース ドキュメント フィールドは、シリアル化中に自動的にキャメル ケース オブジェクト プロパティに変換されます。

Keep in mind that it is your responsibility to populate your Elasticsearch index. To do so, you can use Logstash, a custom state processors or any other mechanism that suits your project (such as an ETL).

Elasticsearch インデックスを設定するのはユーザーの責任であることに注意してください。これを行うには、Logstash、カスタム状態プロセッサ、またはプロジェクトに適したその他のメカニズム (ETL など) を使用できます。

To disable elasticsearch index discovery for non-elasticsearch entities you can set elasticsearch: false in the #[ApiResource] attribute. If this property is absent, all entities will perform an index check during cache warmup to determine if they are on elasticsearch or not.

非elasticsearchエンティティのelasticsearchインデックス検出を無効にするには、 #[ApiResource] 属性でelasticsearch: falseを設定します。このプロパティが存在しない場合、すべてのエンティティはキャッシュのウォームアップ中にインデックス チェックを実行し、elasticsearch にあるかどうかを判断します。

You're done! The API is now ready to use.

あなたは終わった! API を使用する準備が整いました。

Creating custom mapping

If you don't follow the Elasticsearch recommendations, you may want a custom mapping between API Platform resources and Elasticsearch indexes/types.

Elasticsearch の推奨事項に従わない場合は、API プラットフォーム リソースと Elasticsearch インデックス/タイプの間のカスタム マッピングが必要になる場合があります。

For example, consider an index being similar to a database in an SQL database and a type being equivalent to a table. So the User and Tweet resources of the previous example would become user and tweet types in an index named app:

たとえば、インデックスが SQL データベースのデータベースに似ていて、タイプがテーブルに相当すると考えてください。したがって、前の例の User および Tweet リソースは、app という名前のインデックスの user および tweet タイプになります。

# 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)%']
        mapping:
            App\Model\User:
                index: app
                type: user
            App\Model\Tweet:
                index: app
                type: tweet

    #...

Filtering

See how to use Elasticsearch filters and how to create Elasticsearch custom filters in the Filters chapter.

フィルターの章で、Elasticsearch フィルターの使用方法と Elasticsearch カスタム フィルターの作成方法を参照してください。

Creating Custom Extensions

See how to create Elasticsearch custom extensions in the Extensions chapter.

拡張機能の章で Elasticsearch カスタム拡張機能を作成する方法を参照してください。