Elasticsearch の検索(Query DSL)について調べてみた!

前回に引き続き Elasticsearch についてです。今回は検索の Query DSL について調べてみようかと。

チートシート発見したので、ドキュメント詳しく読むのがめんどくさいときは参考にしようと思います。

QueryDSL

Elasticsearch は検索の種類が Query DSL と、SQL DSL とあります。どちらかというと Query DSL の方が一般的かなーと思います。チュートリアルも Query DSL で書かれていましたし。

Query DSLJSONを元に検索を行います。大きく2つの句で構成されています。

  • Leaf query - 特定のフィールドに指定された値があるかを検索します。 match, term, range 句等がそれに当たります。
  • Compound query - 他の Compound query や Leaf query を組み合わせた検索をします。 booldis_max 句等がそれに当たります。

関係性としてはこんな感じかなと。

f:id:bau1537:20200623101320j:plain

具体的な検索の条件は Leaf query 句で指定し、条件の組み合わせに Compound query を使用する、と覚えれば良さそうです。では次に具体的なクエリを見ていきたいと思います。

Boolean query

Compound query の代表的な句は bool 句かなと思います。 bool 句では真偽値の組み合わせによってドキュメントを検索します。 bool 句は最大で4つのタイプ(オカレンスというようです。和訳すると発生ですが、どういう意味...?)の Leaf query を包含できます。例えば must にはそれに一致するドキュメントを検索し、 must_not では一致しないドキュメントを検索します。これらオカレンスを組み合わせることで、複数の条件を指定することができます。例えば以下の例では mustfilter を使用し、計3つの Leaf query で検索条件を指定しています。

f:id:bau1537:20200622175144j:plain

上記の例では以下の条件を満たすドキュメントを検索します。

  • machine.oswin 文字列が含まれる。
  • tagssuccess 文字列が含まれる。
  • geo.srcIN 文字列が含まれる。

filtermust では Leaf query の扱い方が非常によく似ていますが、微妙に違います。どちらもその内容に一致するドキュメントを検索するので、検索結果のドキュメントに違いはありません。が、関連性スコアと言われる値を計算するか、しないか、で差異があります。

関連性スコア

関連性スコアとは調べれば調べるほど色々と出てくるのですが、とりあえずは検索条件にドキュメントがどれほど一致しているかを示す数値のことと覚えれば良さそうです。関連性スコアは返却値の hits.hits._score フィールドに格納されています。

関連性スコアは検索条件の全ての句が影響を与えるわけではないそうです。全ての検索条件には以下の2つのコンテキストがあり、コンテキストによって関連性スコアに影響を与えるかが決定します。

  • query context - 検索条件がドキュメントと一致するかに加え、どの程度一致するかまで調べ、関連性スコアを計算
  • filter context - 検索条件がドキュメントと一致するかのみを調べ、関連性スコアは計算しない

例で上げた bool 句は must が query context であり、 filter は filter context になります。よって、どちらの Leaf query もドキュメントの検索条件として働きますが、関連性スコアに影響を与えるのは must のみになるということですね。

一方で should を使用することで 条件に一致する必要はないけれど、一致すれば関連性スコアを上げるといった事もできます。例えば以下のように書きます。

GET /kibana_sample_data_logs/_search
{
  "query": {
    "bool": {
      "must": [
        { "match": { "machine.os": "win" } },
        { "match": { "tags": "success"  } }
      ],
      "should": { "match": { "geo.src": "IN" } }
    }
  }
}