Elastic CloudのインデックスにCSVデータのドキュメントを追加する方法
基本的にはIndex APIのドキュメントを元にやってるのだが、Elasticさんは材料だけ用意してサンプルのレシピとかあんま載せてくれないからとても苦戦した。
インデックスの作成自体はElastic CloudのKibanaからCSVファイルをアップロードするだけで可能だが、既存のインデックスにCSVデータを追加したい場合、Dev Toolsからはファイル参照ができず、しかもJSONでしか追加できないようです。
今回はこちらの記事のload_csv.pyを大いに参考にしました。いじったのhostはローカルのesでなくクラウドのesに変更したくらいです。
元のCSVファイル
以下のように1行目にヘッダーがあり、カンマ区切り、date形式はyyyy-MM-ddです(date形式は一般的なものであればelastic側が認識してくれるとは思います)。本文中に,"\n\s
などが入っていないことに気をつけましょう。
title,author,created_date,body,url,description,author_image_url
今日の出来事,たくや,2021-10-10,今日はほげほげで..,https://example.com/aaa,たくやの日記です。日々のうんたら..,https://img.example.com/tky
実装
準備
まず任意のディレクトリとファイルをつくり、pipでelasticsearchを入れる。
mkdir es_uploader
cd es_uploader
touch load_csv.py
pip3 install elasticsearch
このes_uploaderディレクトリにアップロード予定のCSVファイルを移動もしくはコピーしておきます。
コード
つづいてload_csv.pyに以下を記述し自分の環境に変更します
from elasticsearch import Elasticsearch
from elasticsearch import helpers
from csv import DictReader
csv_file = "sample.csv" # ここが~/や../のようにパス形式だと上手くいかなかった
index_name = "my-index"
es = Elasticsearch([f"https://username:password@your-original-id.es.asia-northeast1.gcp.cloud.es.io:9243"])
### simple
with open(csv_file, "rt", encoding = "utf-8") as file:
reader = DictReader(file)
for row in reader:
doc = row
print('adding..: ', doc)
es.index(index=index_name, body=doc)
es.close()
endpointはElastic CloudのDeployment画面でコピーできますが、username:password@
を追記した形です。
以下の書き方でもいけるみたいです。
es = Elasticsearch(
"https://username:password@your-original-id.es.asia-northeast1.gcp.cloud.es.io:9243",
http_auth=("username", "password")
)
最後にes.close()
を書いていないとインスタンスがガベージコレクションされた際によくないらしく明示的に追記しました。
実行
実行してあげるとインデックスが追加されるはずです。
python3 load_csv.py
余談
createメソッドを使う場合はid必須だが、indexメソッドならidの指定がない場合はelastic側が自動採番してくれる。また重複を避けたい場合はidによる判定しかできないようで、Web検索エンジンのインデックスの場合はURLか、URLの.や/を-に置き換えたものをidとすべきか検討中。
参考記事
Discussion