はてだBlog(仮称)

私的なブログど真ん中のつもりでしたが、気づけばWebサイト系のアプリケーション開発周りで感じたこと寄りの自分メモなどをつれづれ述べています。2020年6月現在、Elasticsearch、pandas、CMSなどに関する話題が多めです。...ですが、だんだんとより私的なプログラムのスニペット置き場になりつつあります。ブログで述べている内容は所属組織で販売している製品などに関するものではなく、また所属する組織の見解を代表するものではありません。

Full text queries と Term level queries一覧見比べ(Elasticsearch)

Elasticsearchのmatch系のクエリとterm系のクエリを、一覧にして比較してみました。

一覧にすることで、似たようなクエリで、あれ? これどっちだったけというところで振り返りやすくなると思いました。

  • 検索フィールド指定と検索語で、それぞれ単複どう指定できるか整理しました。
  • Elasticsearchでは、検索語の中のワードはデフォルトORらしいのですが、operatorに"and"を指定してクエリを投げるとANDになります。このORとANDを切り替えられるものを◯をつけました。(正確にいうと、公式リファレンスで、operatorプロパティが指定できると記載があったものに◯をつけたつもりですので、ひょっとするとコレ以外にもあるかもしれません。 ... が、みる限りORとANDの概念が存在しえるようなもの*1に◯がついているように見えるのでおそらくあっていると思います。)
  • 実はクエリのシンタックス例は入れ込んでいないのですが、並べて比較することで、シンタックスのプロパティ階層を思い出しやすくなったと思います。もともとある程度クエリのシンタックスに慣れていることが前提ですが...

f:id:azotar:20181206202430p:plain
Full text queries と Term level queries 一覧見比べ

並べてみることで、これまであまり意識していなかったものに気づきました。

  1. multi_matchのmost_fields版: 複数フィールドにざっくり当たって欲しいが、bool-should記法は少しめんどくさい場合に便利
  2. termsのlookupメカニズム:termsは複数の検索語を配列で指定できるが、その配列をある別のインデックスのドキュメントID=1のfollowersフィールドの値とする...というようなクエリ。アプリの変数を介する必要がない。

なお、上記に「Terms Set Query」が漏れていた。のでここに追記。

Terms Set Query

  • 一言でいうと: 検索語の指定はtermsに似ている。
  • 検索対象フィールド:1つ(ただし、このフィルードは配列型になっている)
  • 検索語:配列
  • 検索結果: 検索語の配列で指定した配列のうち、minimum_should_match_fieldで指定した個数以上分の配列内の要素ヒットするようなドキュメント。

何か便利そうな気もするが、ここでは具体的なユースケースは思いつかなかった。

並べてみると分かるのですが...

並べてみると分かるのですが...というと少し強引ですが、

これだけクエリ種類があるといろいろ考えて欲張ってしまうのですが、検索サイトでは、次ぐらいの方針で良いのではと改めて感じました。

  • フリー検索BOXでは検索語はANDが多数派のような気がします。つまるところ自然語風に検索できますというところを特にウリにしない限り、フレーズ検索は使わない戦略を取っても良さそうです。
  • ORで検索したいようなシーンは、ディレクトリ検索(フリーの検索語ではなく、リンクやラベルを選択して選択状態にする)でカバーする使い分け方がすっきりしそうです。
  • term 系は、コード値や特定の属性にぴったりヒットさせる場合に使いますが、スコアリングを高めにして、term、termsで検索する。一方、wildcardやregexpやfuzzyは検索結果が0件や少ない場合に、「もしかしての」バリエーションとして追加で検索するという用途に寄せた方がシンプルになるかもしれません。要は、普通の検索はtermとtermsの使用にとどめる設計方針にしておき、個別の重要なユースケース対応が必要な場合は、「詳細検索」等としてワイルドカードが使える検索窓として別メニューにした方が良い(できればそのようなものは設けない方が良い)という気がしました。

図でまとめているクエリの一覧。

  1. match
  2. match_phrase
  3. match_phrase_prefix
  4. multi_match
    1. best_fields
    2. most_fields
    3. cross_fields
    4. phrase
    5. phrase_prefix
  5. common
  6. query_string
  7. simple_query_string
  8. term
  9. terms
  10. lookupメカニズム
  11. range
  12. exists
  13. prefix
  14. wildcard
  15. regexp
  16. fuzzy
  17. type
  18. ids

*1:例. 検索語の中の単語の順序に意味があるmatch_phraseなどはANDもORもない。