前回に引き続き Elasticsearch についてです。今回は検索の Query DSL について調べてみようかと。
チートシート発見したので、ドキュメント詳しく読むのがめんどくさいときは参考にしようと思います。
QueryDSL
Elasticsearch は検索の種類が Query DSL と、SQL DSL とあります。どちらかというと Query DSL の方が一般的かなーと思います。チュートリアルも Query DSL で書かれていましたし。
Query DSL はJSONを元に検索を行います。大きく2つの句で構成されています。
- Leaf query - 特定のフィールドに指定された値があるかを検索します。
match
,term
,range
句等がそれに当たります。 - Compound query - 他の Compound query や Leaf query を組み合わせた検索をします。
bool
やdis_max
句等がそれに当たります。
関係性としてはこんな感じかなと。
具体的な検索の条件は Leaf query
句で指定し、条件の組み合わせに Compound query
を使用する、と覚えれば良さそうです。では次に具体的なクエリを見ていきたいと思います。
Boolean query
Compound query の代表的な句は bool
句かなと思います。 bool
句では真偽値の組み合わせによってドキュメントを検索します。 bool
句は最大で4つのタイプ(オカレンスというようです。和訳すると発生ですが、どういう意味...?)の Leaf query を包含できます。例えば must
にはそれに一致するドキュメントを検索し、 must_not
では一致しないドキュメントを検索します。これらオカレンスを組み合わせることで、複数の条件を指定することができます。例えば以下の例では must
と filter
を使用し、計3つの Leaf query で検索条件を指定しています。
上記の例では以下の条件を満たすドキュメントを検索します。
machine.os
にwin
文字列が含まれる。tags
にsuccess
文字列が含まれる。geo.src
にIN
文字列が含まれる。
filter
と must
では 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" } } } } }