Kibana4 + Elasticsearch で not_analyzed 指定を忘れた時にやったこと

Elasticsearch をそのまま使うと string フィールドがトークナイズされてしまうので、ユーザーエージェント等スペースを含むフィールドのグラフが意図通り出ない問題に対処した。

真面目にやるなら elasticsearchでダウンタイムなしでインデックスのマッピングを切り替える の方法がいいんだけど、Ruby が必要だったり、エイリアスを作ったりしなければならないので、もっと不真面目にやった時の記録。

環境

やったこと

まずは、今後作成される全ての string のフィールドを not_analyzed にする。

curl -XPOST localhost:9200/_template/strig_not_analyzed_template -d '{
  "template": "*",
  "mappings": {
    "_default_": {
      "dynamic_templates": [
        {
          "string_template": {
            "mapping": {
              "index": "not_analyzed",
              "type": "string"
            },
            "match_mapping_type": "string",
            "match": "*"
          }
        }
      ]
    }
  }
}'

この後、9:00 JST まで待って次の日のインデックスが作成されるのを待つ。

Elasticsearch Reindexing をインストールする。

$ES_HOME/bin/plugin --install org.codelibs/elasticsearch-reindexing/1.4.2
service elasticsearch restart

Elasticsearch Reindexing 1.4.2 は Elasticsearch 1.6.0 でも動いた。

あとは、古いインデックスを一旦新しいインデックスに reindex して、また元に戻すというのを繰り返す。
最新のインデックスは、ログの流し込みが行われているはずなので、除外しておく。
雑なスクリプトでも動けばいいじゃない。

for index_name in access-2015.06.27 access-2015.06.28 access-2015.06.29 access-2015.06.30 access-2015.07.01; do
  curl -XPOST localhost:9200/${index_name}/_reindex/${index_name}_new/?wait_for_completion=true
  curl -XDELETE localhost:9200/${index_name}
  curl -XPOST localhost:9200/${index_name}_new/_reindex/${index_name}/?wait_for_completion=true
  curl -XDELETE localhost:9200/${index_name}_new
done

これで、全てのインデックスの string フィールドは not_analyzed になる。

まとめ

Elasticsearch Reindexing 最高!