Elasticsearchインデックスを作成する

Elasticsearch における 2 つの非常に重要な概念は、ドキュメントインデックスです。

ドキュメントは、関連付けられた値を持つフィールドの集合です。Elasticsearch を使用するには、データをドキュメントに整理し、すべてのドキュメントをインデックスに追加する必要があります。インデックスは、効率的な検索を実行するように設計された高度に最適化された形式で保存されたドキュメントのコレクションと考えることができます。

他のデータベースを使用したことがある場合は、多くのデータベースでスキーマ定義が必要であることをご存知でしょう。スキーマ定義とは、基本的に、保存するすべてのフィールドとそのタイプの説明です。Elasticsearch インデックスは必要に応じてスキーマを使用して構成できますが、データ自体からスキーマを自動的に派生させることもできます。このセクションでは、Elasticsearch が独自にスキーマを判別できるようにします。これは、テキスト、数値、日付などの単純なデータ型には非常にうまく機能します。後ほど、より複雑なデータ型を紹介した後、明示的なスキーマ定義を提供する方法を学習します。

インデックスを作成する

Python クライアント ライブラリを使用して Elasticsearch インデックスを作成する方法は次のとおりです。

この例では、 self.esElasticsearchクラスのインスタンスであり、このチュートリアルではsearch.pySearchクラスに格納されています。Elasticsearch デプロイメントを使用すると、複数のインデックスを保存できます。各インデックスは、上記の例のmy_documentsなどの名前で識別されます。

インデックスも削除できます。

既存のインデックスにすでに割り当てられている名前でインデックスを作成しようとすると、エラーが発生します。インデックスの以前のインスタンスが存在する場合はそれを自動的に削除するインデックスを作成すると便利な場合があります。これは、アプリケーションの開発中にインデックスを複数回再生成する必要がある可能性があるため、特に便利です。

search.pycreate_index()ヘルパー メソッドを追加してみましょう。このファイルをコード エディターで開き、既存の内容はそのままにして、下部に次のコードを追加します。

create_index()メソッドは、まずmy_documentsという名前のインデックスを削除します。ignore_unavailable=Trueオプションは、インデックス名が見つからない場合にこの呼び出しが失敗することを防ぎます。メソッドの次の行は、同じ名前の新しいインデックスを作成します。

このチュートリアルで紹介するサンプル アプリケーションには単一の Elasticsearch インデックスが必要であるため、インデックス名をmy_documentsとしてハードコードしています。複数のインデックスを使用するより複雑なアプリケーションの場合は、インデックス名を引数として受け入れることを検討してください。

インデックスにドキュメントを追加する

Python 用の Elasticsearch クライアント ライブラリでは、ドキュメントはキー/値フィールドの辞書として表されます。文字列値を持つフィールドは、全文検索やキーワード検索のために自動的にインデックスが付けられますが、文字列に加えて、数値、日付、ブール値などの他のフィールド タイプも使用できます。これらのフィールド タイプも、フィルタリングなどの効率的な操作のためにインデックスが付けられます。フィールドがリストまたはサブ項目を含む辞書に設定される複雑なデータ構造を構築することもできます。

ドキュメントをインデックスに挿入するには、Elasticsearch クライアントのindex()メソッドが使用されます。例えば:

index()メソッドからの戻り値は、Elasticsearch サービスによって返される応答です。この応答で返される最も重要な情報は、キー名が_idの項目であり、ドキュメントがインデックスに挿入されたときに割り当てられた一意の識別子を表します。識別子は、ドキュメントを取得、削除、または更新するために使用できます。

ドキュメントを挿入する方法がわかったので、 search.pyで便利なヘルパーのライブラリを構築し続けましょう。Searchクラスに新しいinsert_document()メソッドが追加されました。search.py の下部に次のメソッドを追加します。

このメソッドは、Elasticsearch クライアントと呼び出し元からのドキュメントを受け入れ、そのドキュメントをmy_documentsインデックスに挿入し、サービスからの応答を返します。

: これらの操作はこのチュートリアルでは説明されていませんが、Elasticsearch クライアントはドキュメントを変更および削除することもできます。利用可能なすべての操作について詳しくは、Python ライブラリ ドキュメントのElasticsearch クラス リファレンスを参照してください。

JSON ファイルからのドキュメントの取り込み

新しい Elasticsearch インデックスを設定するときは、大量のドキュメントをインポートする必要がある可能性があります。このチュートリアルでは、スターター プロジェクトに JSON 形式のデータを含むdata.jsonファイルが含まれています。このセクションでは、このファイルに含まれるすべてのドキュメントをインデックスにインポートする方法を学習します。

data.jsonに含まれるドキュメントの構造は次のとおりです。

  • name: 文書のタイトル
  • url: 外部サイトでホストされているドキュメントへの URL
  • summary: 文書の内容の短い要約
  • content: 文書の本文
  • created_on: 作成日
  • updated_at: 更新日(ドキュメントが更新されていない場合は欠落している可能性があります)
  • category: ドキュメントのカテゴリ。 githubsharepoint 、または teams
  • rolePermissions: ロール権限のリスト

この時点で、エディターでdata.jsonを開いて、作業するデータについて理解しておくことをお勧めします。

本質的には、大量のドキュメントをインポートすることは、for ループ内で 1 つのドキュメントをインポートすることと変わりません。data.jsonファイルの内容全体をインポートするには、次のようにします。

このアプローチは機能しますが、拡張性は高くありません。非常に大量のドキュメントを挿入する必要がある場合は、Elasticsearch サービスに同じ回数だけ呼び出しを行う必要があります。残念ながら、各 API 呼び出しにはパフォーマンス コストが伴い、また、サービスには大量の呼び出しを迅速に行うことを妨げるレート制限が設けられています。これらの理由から、Elasticsearch サービスの一括挿入機能を使用するのが最適です。この機能を使用すると、1 回の API 呼び出しで複数の操作をサービスに伝達できます。

以下に示すinsert_documents()メソッドは、 search.pyの末尾に追加する必要があります。bulk()メソッドを使用して、1 回の呼び出しですべてのドキュメントを挿入します。

このメソッドはドキュメントのリストを受け入れます。各ドキュメントを個別に追加する代わりに、 operationsという単一のリストを組み立て、そのリストをbulk()メソッドに渡します。各ドキュメントについて、2 つのエントリがoperationsリストに追加されます。

  • 実行する操作の説明。 indexに設定され、インデックスの名前が引数として指定されます。
  • 文書の実際のデータ

一括リクエストを処理する場合、Elasticsearch サービスは操作リストを最初から調べて、要求された操作を実行します。

インデックスの再生成

このチュートリアルの作業中には、インデックスを数回再生成する必要があります。この操作を効率化するには、 search.pyreindex()メソッドを追加します。

このメソッドは、前に作成したcreate_index()メソッドとinsert_documents()メソッドを組み合わせて、1 回の呼び出しで古いインデックス (存在する場合) を破棄し、新しいインデックスを構築して再設定できるようにします。

注意: 非常に多くのドキュメントをインデックスする場合は、ドキュメントのリストを小さなセットに分割し、各セットを個別にインポートするのが最適です。

このメソッドを簡単に呼び出せるようにするには、 flaskコマンドを通じて公開しましょう。コード エディターでapp.py を開き、下部に次の関数を追加します。

@app.cli.command()デコレータは、Flask フレームワークにこの関数をカスタム コマンドとして登録するように指示します。これはflask reindexとして使用できるようになります。コマンドの名前は関数の名前から取得され、Flask は--helpドキュメントで docstring を使用するため、ここに docstring が含まれます。

reindex()関数からの応答 (Elasticsearch クライアントのbulk()メソッドからの応答) には、適切なステータス メッセージを作成するために使用できる便利な項目がいくつか含まれています。特に、 response['took']は呼び出しの継続時間(ミリ秒単位)であり、 response['items']は各操作の個々の結果のリストです。これは実際には直接役立ちませんが、リストの長さによって挿入されたドキュメントの数を知ることができます。

ターミナル セッションからflask --helpを実行して、Python 仮想環境がアクティブになっていることを確認し、それがどのように見えるかを確認します (ターミナル セッションでまだ Flask アプリケーションが実行されている場合は、2 番目のターミナル ウィンドウを開くことができます)。ヘルプ画面の最後の方に、Flask フレームワークによって提供される他のオプションとともに、使用可能なコマンドとしてreindexオプションが表示されます。

クリーンなインデックスを生成したい場合は、 flask reindexを実行するだけです。

最先端の検索体験を構築する準備はできましたか?

十分に高度な検索は 1 人の努力だけでは実現できません。Elasticsearch は、データ サイエンティスト、ML オペレーター、エンジニアなど、あなたと同じように検索に情熱を傾ける多くの人々によって支えられています。ぜひつながり、協力して、希望する結果が得られる魔法の検索エクスペリエンスを構築しましょう。

はじめましょう