Elasticsearchは「高速な全文検索エンジン」を売りにしたデータベースのようなものです。そこには、ドキュメントだけではなく、数値や位置情報といった様々な形式のデータを蓄積することができます。
Elasticsearchに蓄積したデータは、何らかの形で分析し、活用することでその価値を発揮します。
Pythonは機械学習やデータ分析のライブラリが豊富なので、そういった分析に用いられることが多いです。つまり、PythonとElasticsearchを連携させることで、よりデータ活用の可能性が広がります。
今回は、Elasticsearchに蓄積されたデータをPythonを使って取り出す方法を紹介していきます。
Elasticsearchのライブラリをインストールする
Python環境に、Elasticsearchのライブラリをインストールします。
pipの場合は、
pip install elasticsearch
Anacondaの場合は
conda install elasticsearch
でインストールします。
PythonからElasticsearchに接続する
まずは、PythonからElasticsearchに接続します。
シンプルなコネクションは以下のようにします。
from elasticsearch import Elasticsearch
es = Elasticsearch("http://localhost:9200")
上記では、LocalhostのElasticsearchに接続しています。
Elasticsearchに認証設定をしている場合
認証設定をしている場合は、以下のようにhttp_auth= でユーザ名とパスワードを指定します。
es = Elasticsearch(
"http://localhost:9200",
http_auth=("user_id", "password")
)
データを取得する
コネクションを張ったところで、指定したインデックスのドキュメントを取得します。
Elasticsearchのインデックスからのドキュメントの取得方法は、大きく2通りあります。
今回は、以下のインデックスからデータを取得してみます。時系列となる情報は含まれていません。
検索方法① クエリで検索
Elasticsearchでは、JSON形式でクエリを記述し、お目当てのドキュメントを取得します。
Pythonからでも、同様のクエリを用いてドキュメントを取得することができます。
ちなみに、クエリやサイズを指定しない場合は、インデックスの全件が取得されます。
#"CRIM"が0.06以下のドキュメントを取得
query = {
"query": {
"range": {
"CRIM": {
"lt": 0.06
}
}
}
}
#インデックス"boston"を対象に検索、5件を取得
SearchResult = es.search(index="boston", body=query, size=5)
上記のコードでは、”CRIM”が0.06以下のレコードを取得しています。
取得結果はSearchResultに格納されます。SearchResultは辞書型で、以下のような構成になります。
ここではまだお目当てのレコードやデータは見当たりません。目当てのデータは、”hits”の中にあります。
ところがまだお目当てのデータは出てきません。
この中の”hits” つまり、”hits”を2度入ったところにレコードが格納されているのです。
レコードの各データは、さらに1階層奥の”_source”の中にあります。
_sourceにあるデータをPythonで表示してみます。
#取得レコード全件
result = SearchResult["hits"]["hits"]
#各レコードのデータを表示
for record in result:
print(record["_source"])
結果は、以下のようになります。
{'B': 396.9, 'CHAS': 0, 'TAX': 296, 'CRIM': 0.00632, 'PTRATIO': 15.3, 'DIS': 4.09, 'ZN': 18.0, 'INDUS': 2.31, 'RAD': 1, 'LSTAT': 4.98, 'NOX': 0.538, 'RM': 6.575, 'AGE': 65.2}
{'B': 396.9, 'CHAS': 0, 'TAX': 242, 'CRIM': 0.02731, 'PTRATIO': 17.8, 'DIS': 4.9671, 'ZN': 0.0, 'INDUS': 7.07, 'RAD': 2, 'LSTAT': 9.14, 'NOX': 0.469, 'RM': 6.421, 'AGE': 78.9}
{'B': 392.83, 'CHAS': 0, 'TAX': 242, 'CRIM': 0.02729, 'PTRATIO': 17.8, 'DIS': 4.9671, 'ZN': 0.0, 'INDUS': 7.07, 'RAD': 2, 'LSTAT': 4.03, 'NOX': 0.469, 'RM': 7.185, 'AGE': 61.1}
{'B': 394.63, 'CHAS': 0, 'TAX': 222, 'CRIM': 0.03237, 'PTRATIO': 18.7, 'DIS': 6.0622, 'ZN': 0.0, 'INDUS': 2.18, 'RAD': 3, 'LSTAT': 2.94, 'NOX': 0.458, 'RM': 6.998, 'AGE': 45.8}
{'B': 394.12, 'CHAS': 0, 'TAX': 222, 'CRIM': 0.02985, 'PTRATIO': 18.7, 'DIS': 6.0622, 'ZN': 0.0, 'INDUS': 2.18, 'RAD': 3, 'LSTAT': 5.21, 'NOX': 0.458, 'RM': 6.43, 'AGE': 58.7}
取得したレコード5件分のデータが表示されました。
検索方法② idでドキュメントを検索
idを指定することで、インデックス内のドキュメント1件を検索取得することができます。
取得にはget_source()を用います。
result = es.get_source(index="boston",id="mQabSnkBZJ_lCnbBHt5n")
取得したデータはJSONの構造になっている
検索したデータは、辞書型で取得します。なので、特定のパラメータを取得する場合は、通常の辞書型と同じように指定します。
検索方法②のresultを例に見てみます。
print(result["CRIM"])
>>Output
0.03237
“CRIM”の値を取得できました。
まとめ
PythonからElasticsearchのデータを取得する方法を紹介しました。
今回は辞書型形式のまま取得しましたが、データ分析を行うに当たっては、pandasと組み合わせたほうが便利です。
今後は、Elasticsearchから取得したデータをデータフレームの形にするまでのサンプルを紹介できればと思います^^
ではでは👋