Amazon Elasticsearch Service で Search Template が利用できるようになりました

Elasticsearch Service

こんにちは、藤本です。

現地時間 4/11 に Amazon Elasticsearch Service で Search Template が利用可能となりました。

概要

Amazon Elasticsearch Service は今まで Search Template のエンドポイントは利用できましたが、Mustache の利用が無効化されていました。つまり事実上 Search Template を使えない状況でした。

それが今回のアップデートで Search Template を利用可能となりました。ただし、バージョン 5.1 のみが対象で、1.5、2.3 は対象外です。

Search Template

Elasticsearch は JSON 形式の構文によって様々な検索や、集計を行うことができます。一つのクエリで多くの結果を受け取ることができます。ですが、複雑なクエリとなると、クエリの JSON が複雑になります。それをアプリケーションで JSON を作り、管理するのは大変です。

そこで Search Template を利用することで Elasticsearch にクエリのテンプレートを登録しておき、アプリケーションからはパラメータを与えるだけで検索、集計結果を受け取ることができます。これにより、アプリケーション側でクエリを管理する必要がなくなります。クエリのチューニングもアプリケーションのソースコードを改修せずとも Elasticsearch 側で行えるのも嬉しいところです。

イメージが湧きづらいかもしれないのでどんな動作になるかご紹介します。

まずは Search Template を登録します。今回はシンプルにMatch Queryで検索キーワードをパラメータとして受け取るクエリです。

POST _search/template/1
{
    "template": {
        "query": {
            "match": {
                "post_content": "{{query_string}}"
            }
        }
    }
}
---------------------------------------------------------------------------
{
  "acknowledged": true
}

次にこのテンプレートを利用して、クエリしてみます。インデックス名はdevio、id は上で指定したテンプレートのID、パラメータとして上でパラメータ化したquery_stringに検索キーワードを与えます。今回は「aurora」で検索します。

GET devio/_search/template
{
  "id": "1",
  "params": {
    "query_string": "aurora"
  }
}
---------------------------------------------------------------------------
{
  "took": 10,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 55,
    "max_score": 9.537851,
    "hits": [
      {
:

結果は長くなったので省略していますが、55件のヒットがあり、なんとなく検索できていることがわかります。イメージ湧きましたでしょうか。パラメータ化した{{query_string}}こそ Mustache の構文となります。

Mustache

Mustache は OSS のテンプレートエンジンです。テンプレートに対して、パラメータを与えることで、出力を得ることができます。Mustache は様々な構文を利用でき、変数、ループ、if文などを実装することができます。Search Template は Mustache をテンプレートエンジンに使用しています。

例えば、以下のような書き方となります。

変数
  • テンプレート
{{var}}
  • パラメータ
{ "var" : "value" }
  • 出力
value
if文
  • テンプレート
{{#var}}display{{/var}}
  • パラメータ
{ "var" : true }
  • 出力
display

var に false が与えられた場合は display が表示されません。

ループ
  • テンプレート
{{#var}}
  {{name}}
{{/var}}
  • パラメータ
{
  "var" : [
    { "name" : "aaa" },
    { "name" : "bbb" },
    { "name" : "ccc" }
]}
  • 出力
aaa
bbb
ccc

配列の中身を順次処理します。シンプルで分かりやすいですね。

Amazon Elasticsearch Service 2系の場合

ちなみに 2系の場合は Mustache の構文を使って、Search Template のエンドポイントをコールすると以下のようなエラーが返ってきます。

$ curl search-es2-xxxxxxxxxxxxxxx.ap-northeast-1.es.amazonaws.com/_search/template -d '{
  "inline": {
    "query": {
      "match": {
        "post_content": "{{query_string}}"
      }
    }
  },
  "params": {
    "query_string": "aurora"
  }
}'
---------------------------------
{"error":{"root_cause":[{"type":"script_exception","reason":"scripts of type [inline], operation [search] and lang [mustache] are disabled"}],"type":"search_phase_execution_exception","reason":"all shards failed","phase":"query","grouped":true,"failed_shards":[{"shard":0,"index":".kibana-4","node":"kI0rF7RVRUq1RwaE4zWQZA","reason":{"type":"script_exception","reason":"scripts of type [inline], operation [search] and lang [mustache] are disabled"}}]},"status":500}

このように Mustache が無効化されている旨のエラーが返ってきます。

まとめ

いかがでしたでしょうか? Amazon Elasticsearch Service は、ダイナミックスクリプティングが使えなかったり、reindex API が使えなかったり、今回の Search Template が使えなかったりといくつかの制限がありましたが、徐々に制限緩和して利便性が高いものになってきました。個人的には、VPC 対応早く!というところです。AutoScaling 環境だと NAT がほぼ必須になるのがなぁ。。

参考サイト

AWS Cloud Roadshow 2017 福岡