Elasticsearch Pythonクライアントのセットアップ

このセクションでは、Python 用の Elasticsearch クライアント ライブラリをインストールし、それを使用して Elasticsearch サービスに接続します。

インストール

Elasticsearch クライアント ライブラリは、 pipとともにインストールされる Python パッケージです。先ほど作成した仮想環境がアクティブになっていることを確認し、次のコマンドを実行してクライアントをインストールします。

pip install elasticsearch

潜在的な非互換性を回避するには、インストールする Elasticsearch クライアント ライブラリのバージョンが、使用している Elasticsearch スタックのバージョンと一致していることを確認してください。

すべての依存関係を反映させたrequirements.txtファイルを常に最新の状態に保つことをお勧めします。このファイルを更新して、新しくインストールされたパッケージを含めるのは良いタイミングです。ターミナルから次のコマンドを実行します。

pip freeze > requirements.txt

Elasticsearchに接続する

Elasticsearch サービスへの接続を作成するには、適切な接続オプションを使用してElasticsearchオブジェクトを作成する必要があります。

コード エディターで、 search-tutorial ディレクトリに新しい search.py ファイルを作成します。search.py ファイルでは、すべての検索関数が定義されます。検索機能用に別のファイルを用意する理由は、このファイルを抽出して後で自分のプロジェクトに追加するのが簡単になるからです。

search.py に次のコードを入力して、 Searchクラスを追加します。

import json
from pprint import pprint
import os
import time

from dotenv import load_dotenv
from elasticsearch import Elasticsearch

load_dotenv()


class Search:
    def __init__(self):
        self.es = Elasticsearch()  # <-- connection options need to be added here
        client_info = self.es.info()
        print('Connected to Elasticsearch!')
        pprint(client_info.body)

ここには解明すべきことがたくさんあります。インポート直後に呼び出されるload_dotenv()関数は、python-dotenvパッケージから取得されます。このパッケージは.envの操作方法を知っていますパスワードやキーなどの構成変数を保存するために使用されるファイル。load_dotenv()関数は.envに格納されている変数を読み取ります。ファイルにそれらを環境変数として Python プロセスにインポートします。

Searchクラスには、 Elasticsearchクライアント クラスのインスタンスを作成するコンストラクターがあります。ここには、Elasticsearch サービスと通信するためのすべてのクライアント ロジックが存在します。サービスに適した接続オプションを含める必要があるため、この行は現在不完全であることに注意してください。あなたのケースに適用されるオプションについては以下で説明します。作成されると、 Elasticsearchオブジェクトはself.esという名前のインスタンス変数に格納されます。

クライアント オブジェクトが Elastic Cloud デプロイメントと通信できることを確認するために、 info()メソッドが呼び出されます。このメソッドは、基本情報を要求するサービスを呼び出します。この呼び出しが成功した場合、サービスへの有効な接続があるものと想定できます。

次に、このメソッドは接続が確立されたことを示すステータス メッセージを出力し、Python のpprint関数を使用して、サービスから返された情報を読みやすい形式で表示します。

注意: Python 標準ライブラリの json パッケージがこのファイルにインポートされていますが、使用されていないことに気付いたかもしれません。このパッケージは後で使用されるため、このインポートを削除しないでください。

Searchクラスのコンストラクターを完了するには、 Elasticsearchオブジェクトに適切な接続オプションを指定する必要があります。次のサブセクションでは、Elastic Cloud および Docker のインストール方法に必要なオプションについて説明します。

Elastic Cloud デプロイメントに接続する

手順に従ってElastic Cloud デプロイメントを作成した場合、デプロイメントの Cloud ID と API キーを知っておく必要があります。これらは機密値であるため、アプリケーション コードに直接含めることはお勧めできません。代わりに.envを作成してください(ドットエンブと発音) ファイルには、これらの秘密を安全に保存できます。

お気に入りのコードエディタを開き、 search-tutorialプロジェクトディレクトリに.envという名前の新しいファイルを作成します。(先頭のドットを忘れないでください)。このファイルに次の内容を入力します。

ELASTIC_CLOUD_ID="paste your Cloud ID here"
ELASTIC_API_KEY="paste your API Key here"

注意: このプロジェクトをソース管理リポジトリにコミットする予定の場合は、 .envを含めないようにしてください。ファイルを保存して、Elastic アカウントの資格情報が侵害されるのを防ぎます。

gitを使用する場合は、 .gitignoreの末尾に次の行を追加します。ファイル(まだファイルが存在しない場合は新しいファイルを作成してください):

.envに資格情報を入力したらファイルで、 search.pySearchクラス コンストラクターに戻り、最初の行を次のように編集します。

class Search:
    def __init__(self):
        self.es = Elasticsearch(cloud_id=os.environ['ELASTIC_CLOUD_ID'],
                                api_key=os.environ['ELASTIC_API_KEY'])
        # ...

cloud_idおよびapi_key引数の値は、Python がos.environ辞書に保持する環境から抽出されます。これらの変数は.envから読み取られますファイルに保存され、 load_dotenv()関数によってこの辞書に保存されます。

セルフホスト型Elasticsearch Dockerコンテナに接続する

Docker を使用してローカルでホストされた Elasticsearch サービスを実行することを選択した場合、必要な接続オプションは接続エンドポイントのみです。search.pySearchクラス コンストラクターの最初の行を次のように編集します。

class Search:
    def __init__(self):
        self.es = Elasticsearch('http://localhost:9200')
        # ...

このバージョンのコンストラクターでは、 Elasticsearchオブジェクトは Elasticsearch サービスの最上位エンドポイントへの URL (通常はhttp://localhost:9200 ) を使用してインスタンス化されます。Docker の手順では暗号化と認証が明示的に無効になっているため、資格情報を提供する必要がないことに注意してください。

接続をテストする

この時点で、Elasticsearch サービスに接続する準備が整いました。これを行うには、Python 仮想環境がアクティブになっていることを確認してから、 pythonと入力して Python 対話型セッションを開始します。使い慣れた>>>プロンプトが表示され、そこに Python ステートメントを入力できます。

次のようにSearchクラスをインポートします。

from search import Search

次に、新しいクラスをインスタンス化します。

es = Search()

接続メッセージが表示され、その後にクライアントのinfo()メソッドによって返された情報が表示されます。識別子とバージョン番号の違いを除けば、出力は次のようになります。

Connected to Elasticsearch!
{'cluster_name': 'ad552eba959043158be67dfc021e91cdc',
 'cluster_uuid': 'ks_HfcCdSf2adeKQEsk9gL',
 'name': 'instance-0000000000',
 'tagline': 'You Know, for Search',
 'version': {'build_date': '2023-11-04T10:04:57.184859352Z',
             'build_flavor': 'default',
             'build_hash': 'b4a62ac808e886ff032700c391f45f1408b2538c',
             'build_snapshot': False,
             'build_type': 'docker',
             'lucene_version': '9.7.0',
             'minimum_index_compatibility_version': '7.0.0',
             'minimum_wire_compatibility_version': '7.17.0',
             'number': '8.13.0'}}

エラーが発生した場合は、 .envに正しい認証情報を入力したことを確認してください。Elastic Cloud デプロイメントを使用している場合は、ファイルに記録されている内容を確認してください。また、セルフホスト型デプロイメントの場合は、指示に従ってコンピューターで Elasticsearch Docker コンテナーを実行していることを確認してください。

ElasticsearchをFlaskアプリケーションに統合する

このセクションの最後のステップは、これまでに行った作業を、先ほどインストールした小さな Flask アプリケーションに統合することです。目標は、アプリケーションの起動時に Elasticsearch への接続を自動的に作成することです。

これを実現するには、コード エディターでapp.pyを開きます。既存のインポートの下にsearch.py モジュールのインポート ステートメントを追加します。

from search import Search

次に、 app変数が作成される行を見つけて、その直後に新しいSearchクラスのインスタンスを作成します。

es = Search()

それでおしまい!これで、アプリケーションには必要に応じて使用できるesオブジェクトが作成されました。まだターミナルで Flask アプリケーションを実行している場合は、ファイルを保存するとすぐにアプリケーションが再読み込みされるのがわかるはずです。再ロードの結果、 Searchクラスのコンストラクターによって出力された接続情報が表示され、今後アプリケーションが再起動するたびに引き続き表示されます。

Flask アプリケーションを実行していない場合は、ここで起動するのがよいでしょう。ターミナル ウィンドウでプロジェクト ディレクトリに移動し、Python 仮想環境をアクティブ化して、次のコマンドでアプリケーションを起動します。

flask run

エラーが発生した場合のトラブルシューティングに役立つように、Elasticsearch クライアントが統合されたapp.pyの完全なコピーを以下に示します。

import re
from flask import Flask, render_template, request
from search import Search

app = Flask(__name__)
es = Search()


@app.get('/')
def index():
    return render_template('index.html')


@app.post('/')
def handle_search():
    query = request.form.get('query', '')
    return render_template(
        'index.html', query=query, results=[], from_=0, total=0)


@app.get('/document/<id>')
def get_document(id):
    return 'Document not found'

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

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

はじめましょう