Elasticsearch Full Text Queries と Term Level Queries の違いを理解するだけで仲良くなれる
クイックスタートでハマりやすいクエリ種類
こんにちはクニです。今回は Elasticsearch を使い始めてまもない開発者がよくハマるクエリーの書き方について紹介したいと思います。
よくあるクイックスタートでヒットしない現象
まず、ドキュメントをインデックス。以下の例では、user フィールドに、Kunihiko Kido
と言う文字列を設定して登録しています。
curl -XPOST localhost:9200/blog/posts -d '
{
"user": "Kunihiko Kido"
}'
次にインデックスしたドキュメントを検索。
curl -XGET localhost:9200/blog/posts/_search -d '
{
"query": {
"term": {
"user": "Kunihiko Kido"
}
}
}'
この結果はどうなるでしょうか?
検索結果は0件です。ドキュメントの値も検索の値もどちらも同じ値を指定していますが、残念ながらヒットしません。
ヒットしない原因は?
なぜヒットしないのでしょう?
まず、user フィールドのインデックスは Standard Analyzer
によって言語処理され以下のように作成されています。
[kunihiko][kido]
一方、検索時に指定した文字列は、term
クエリーを使用しているため、何も処理されず指定した文字列のまま検索します。
[Kunihiko Kido]
このように、最終的に処理された結果が異なるため、ヒットしませんでした。
terms クエリを使用して完全一致で検索したい場合は、インデックス時も言語処理されない*.keyword
フィールドを対象に検索することで、マッチすることができます。(5.x 系)
curl -XGET localhost:9200/blog/posts/_search -d '
{
"query": {
"term": {
"user.keyword": "Kunihiko Kido"
}
}
}'
また、大文字小文字を区別せずに曖昧に検索したいのであれば、terms クエリの代わりに match クエリを使用することも可能です。
curl -XGET localhost:9200/blog/posts/_search -d '
{
"query": {
"match": {
"user": "Kunihiko Kido"
}
}
}'
Full text queries と Term level queries の違いを理解すれば迷わない
Elasticsearch が提供するクエリーの種類は大きく、Full text queries と Term level queries があります。
先ほどの例では、terms クエリは Term level queries に分類されます。また、match クエリは Full text queries に分類されます。
それぞれどのクエリがどちらに該当するのかは以下のリンク先を確認してください。
リファレンスには色々書いてありますが、これだけ理解しておけば大丈夫です。
Full text queries は言語処理される。
Term level queries は言語処理されない。
検索対象フィールドの言語処理の有無によって、Full text 系のクエリを使うのか、Term level 系のクエリを使うのか考えればひとまず、クイックスタートでよくあるヒットしない現象はすぐに解決できるでしょう。
まとめ
もう一度言います。
Full text queries は言語処理される。Term level queries は言語処理されない。
これだけ覚えておくだけで、Elasticsearch と仲良くなれますよ。