💬

Elastic CloudのインデックスにCSVデータのドキュメントを追加する方法

2021/10/10に公開

基本的にはIndex APIのドキュメントを元にやってるのだが、Elasticさんは材料だけ用意してサンプルのレシピとかあんま載せてくれないからとても苦戦した。

インデックスの作成自体はElastic CloudのKibanaからCSVファイルをアップロードするだけで可能だが、既存のインデックスにCSVデータを追加したい場合、Dev Toolsからはファイル参照ができず、しかもJSONでしか追加できないようです。

今回はこちらの記事のload_csv.pyを大いに参考にしました。いじったのhostはローカルのesでなくクラウドのesに変更したくらいです。

https://kazuhira-r.hatenablog.com/entry/2020/01/01/012853

元のCSVファイル

以下のように1行目にヘッダーがあり、カンマ区切り、date形式はyyyy-MM-ddです(date形式は一般的なものであればelastic側が認識してくれるとは思います)。本文中に,"\n\sなどが入っていないことに気をつけましょう。

sample.csv
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に以下を記述し自分の環境に変更します

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とすべきか検討中。

参考記事

https://github.com/elastic/elasticsearch-py

https://qiita.com/satto_sann/items/8a63761bbfd6542bb9a2

https://github.com/elastic/elasticsearch-py/issues/516

https://stackoverflow.com/questions/33573692/avoid-duplicate-documents-in-elasticsearch

Discussion