第4回 Elasticsearch 入門 検索の基本中の基本
今回は「検索の基本中の基本」について解説したいと思います。この Elasticsearch 入門シリーズは今回で4回目になりますが、検索エンジンなのにやっと検索の話です。
Elasticsearch の検索のパワーをフルに活用するには、以下の内容を理解する必要があります(検索や集計の精度を向上させるなど)。
- Mapping: フィールドの型や分析方法の設定
- Analysis: 言語処理や正規化などフィールドの値の加工について
- Query DSL: JSON フォーマットによる検索条件の組み立て
今回はこれらのことは一旦置いておいて、検索の基本中の基本について解説します。
サーチ API
Elasticsearch のサーチ API の基本ルールは以下の URL パターンです。ドキュメントの管理同様わかりやすくなっています。
GET|POST /{index}/{type}/_search
検索条件はクエリーストリングで指定する簡単な条件指定と、複雑な検索条件を JSON 形式で組み立てる Query DSL をサポートしています。(詳しくは別の機会に説明する予定です。)
メソッドは、GET と POST の両方を提供しています。 GET メソッドでも body の内容を受け付けています。
※ 注意: クライアントによっては、HTTP GET メソッド使用時に body の内容をリクエストしない場合があります。そのため、基本的には body の内容をリクエストする場合は POST メソッドを使用したほうが良いでしょう。
サーチ API のバリエーション
Elasticsearch はインデックスやタイプを横断で検索できるようになっているため、上記の基本ルールを元に柔軟な指定が可能です。
以下はそのバリエーション例です。
- /_search
すべてのインデックス内のすべてのタイプを対象に検索する - /blog/_search
blog インデックス内のすべてのタイプを対象に検索する - /blog,author/_search
blog と author インデックス内のすべてのタイプを対象に検索する - /b*,a*/_search
b から始まるインデックスと、a から始まるインデックス内のすべてのタイプを対象に検索する - /blog/posts/_search
blog インデックス内の posts タイプを対象に検索する - /blog,author/posts,users/_search
blog と author インデックス内の posts と users タイプを対象に検索する - /_all/posts,users/_search
すべてのインデックス内の posts と users タイプを対象に検索する
バリエーションは豊富ですが、直感的で覚えやすい印象です。 また、Type (RDB のテーブルに相当する仕組み)を管理する上位の Index レベルでも横断的な検索ができるのは、マルチテナンシな仕組みを持つ Elasticsearch の特徴ではないでしょうか。
本番環境の検索はエイリアス名を使おう
インデックスには、エイリアス名を定義することができます。 サーチエンドポイントでエイリアスを指定するには、インデックス名の代わりにエイリアス名を指定するだけです。
さらに、複数のインデックスに同じ名前のエイリアスを定義することができます。そのため1つのエイリアスを指定するだけです複数のインデックスを対象に検索できます。
エイリアス名を使うことで、アプリケーションの修正なく検索対象のインデックスを柔軟に変更できます。本番環境の検索はエイリアス名を使いましょう。
- 参考: Index Aliases (Elasticsearch 公式 リファレンス)
ページング
SQL では LIMIT を使って、1ページあたりの結果を取得します。Elasticsearch では、size と from パラメータを使います。
- size: 1度に検索結果を取得する数を指定します。デフォルトは10です。
- from: スキップする検索結果数を指定します。デフォルトは0です。
GET /_search?size=5
GET /_search?size=5&from=5
GET /_search?size=5&from=10
分散システムのページングは制限があるので理解しておこう
まず、5つのシャードから構成される1つのインデックスから検索結果にマッチするトップ10を返す場合を説明します。
検索条件にマッチするドキュメントを5つのシャードそれぞれから10件づつ取得します。その後その50件全ての結果をソートしたのち全体でトップ10件が決定され結果が返る仕組みです。
これが分散システムでの基本的なページングの動きです。
この動きを深いページングで想像してみましょう。例えば、10,001件目から10,010件目を取得する場合、それぞれのシャードからトップ10,010をそれぞれ取得します。その後合計50,050を対象にソートを実行、そして不要な50,040件を破棄して残った10件を返すことになります。
考えただけでも重そうな処理ですね。このような仕組みのため、多くの検索エンジンはページグして取得できる件数に制限があるので覚えておきましょう。
大量のデータをページングして取得するには
すべてのデータダンプしたり大量のデータを一度に取得する場合は、通常の検索とは別の方法が用意されています。
※ 参考: scroll and scan APIs (Elasticsearch 公式 リファレンス)
まとめ
いかがでしたでしょうか? Elasticsearch は他のデータベースに比べ、複数のデータベースを横断して検索することがごく当たり前の用途として提供されています。
また、その検索結果も異なるスキーマのドキュメントが混在することも特別なことではありません。しかし、分散システムであるが故の制限もあります。検索エンジンの特徴を理解してアプリケーションの設計に生かしてください。
Originally published at dev.classmethod.jp.