elasticsearchのfieldを一部修正する
概要
elasticesearchに入れたデータを後で修正したくなった時の修正手順。
update by queryを使います。
バージョン情報など
elasticsearch-6.0.0-alpha2
kibana-6.0.0-alpha2
前提
ユーザーのアカウント情報を持つaccountというindexを作成しました。
fieldの内容としては、氏名や電話番号、住所などが入っています。
「ユーザーの増加にともなってuser_idの見直しが必要になった」というシチュエーションを想定します。(先見性の無さ....)
新たなユーザー、yokohama takashiさんが登録されましたが、このユーザーのuser_idが既存のユーザーと被ってしまいました。
もともとuser_idの命名規則が、「firstnameの頭文字」.「lastname」だったので、idが被らないように変更する必要があります。
user_idで検索すると2件ヒットしてしまいます。
この記事では、t.yokohamaのuser_idを、
lastname.firstnameの形式に書き換える手順を書きます。
手順
1. 変更したいドキュメントの条件をqueryで定義する。
今回は取り急ぎ、t.yokohamaというuser_idを持つユーザーのuser_idのみを変更します。
そのためqueryは下記のようになります。
"query": { "term": { "user_id.keyword": { "value": "t.yokohama" } } }
2. update by query
結論から書くと、下記のjsonをConsole上で実行すれば、updateができます。
POST account/_update_by_query { "query": { "term": { "user_id.keyword": { "value": "t.yokohama" } } }, "script": { "inline": "ctx._source.user_id = ctx._source.firstname + '.' + ctx._source.lastname", "lang": "painless" } }
query部分で、対象とするドキュメントを絞り、script部分で処理の内容を書きます。
scriptではpainlessを使っているので、ctx._source.field名でフィールドにアクセスできます。
これを実際に実行すると...
無事書き換わりました
めでたしめでたし
その他メモ
・reindex APIでもscriptが使えるので、部分的に書き換えて別indexに入れることもできる。
追記(10/1)
reindex APIを使った方法も追記して欲しいとのコメントをいただいたので追記します。
下記のようなリクエストを実行すれば同じようなことができます。
(queryの部分を省けば、全ドキュメントを対象にできます。)
POST _reindex { "source": { "index": "account" }, "dest": { "index": "account_dest" }, "script": { "inline": "ctx._source.user_id = ctx._source.firstname + '.' + ctx._source.lastname", "lang": "painless" } }
※この場合、account indexが書き換えられるのでは無く、account_destという別のindexが作成されるので、もう一度reindex APIで元のindexに書き戻すか、aliasを利用してください。