2016-03-15

ElasticSearchの設定あれこれ

前回の記事のElasticSearchの設定に関する補足。

アナライザが効いているかどうかの確認方法

形態素解析とユーザ辞書が効いているかどうかを確認します。
$ curl -X GET "http://localhost:9200/logstash-2016.02.29/_analyze?pretty" -d "白石麻衣"

姓名で分割されず「白石麻衣」で返ってくれば、ユーザ辞書が効いてます。

{
  "tokens" : [{
    "token" : "白石麻衣",
    "start_offset" : 0,
    "end_offset" : 4,
    "type" : "word",
    "position" : 0
  }]
}

日本語の形態素解析がうまくいっているかどうかは以下で確認可能です。

$ curl -X GET "http://localhost:9200/logstash-2016.02.29/_analyze?pretty" -d "白石美帆"

形態素解析がうまくいっていると、「白石」と「美帆」が返ってきます。

{
  "tokens" : [{
    "token" : "白石",
    "start_offset" : 0,
    "end_offset" : 2,
    "type" : "word",
    "position" : 0
  },
  {
    "token" : "美帆",
    "start_offset" : 2,
    "end_offset" : 4,
    "type" : "word",
    "position" : 1
  }]
}

インデックステンプレートについて

インデックスが作成されるときに適用されるマッピングのテンプレートになります。今回の場合、fluentdから動的にindexを作っていくので、インデックステンプレートを定義して項目ごとのアナライザや日付フォーマットの設定を行います。
$ curl -X POST http://localhost:9200/_template/template_idle \
-H "Content-type: application/json" -d '{
  "template" : "logstash-*",
  "settings": {
    "analysis": {
      "filter": {
        "pos_filter": {
          "type": "kuromoji_part_of_speech",
          "stoptags": ["接続詞",...}
      },
      "tokenizer": {
        "ja_tokenizer": {
          "type": "kuromoji_tokenizer",
          "mode": "search",
          "user_dictionary": "userdict_ja.txt"
        }
      },
      "analyzer": {
        "default": {
          "type": "custom",
          "tokenizer": "ja_tokenizer",
          "filter": ["pos_filter"]
        },
        "ja_analyzer": {
          "type": "custom",
          "tokenizer": "ja_tokenizer",
          "filter": ["pos_filter"]
        }
      }
    }
  },
  "mappings": {
    "idle": {
      "dynamic_templates": [ 
        {
          "string_template": {
            "mapping": {
              "index": "analyzed",
              "type": "string"
            },
            "match_mapping_type": "string",
            "match": "text"
          }
        },
        {
          "string_template": {
            "mapping": {
              "index": "not_analyzed",
              "type": "string"
            },
            "match_mapping_type": "string",
            "match": "*"
          }
        }
      ],
      "properties": {
        "@timestamp": {
          "type": "date",
          "format": "EEE MMM dd HH:mm:ss Z yyyy"
        },
        "created_at": {
          "type": "date",
          "format": "EEE MMM dd HH:mm:ss Z yyyy"
        },
        "timestamp_ms": {
          "type": "date",
          "format": "epoch_millis"
        }
      }
    }
  }
}'

インデックステンプレートの検証

適当なドキュメントを作成します。以下のコマンド前にはlogstash-xxxxのインデックスは作成されていない前提です。
$ curl -X POST http://localhost:9200/logstash-xxxx/idle/1 \
 -H "Content-type: application/json" -d '{
  "text": "******",
  ...
}'

正常に作成できればdate型に関しては問題ないことになります。アナライザは上記に書いた方法で検証します。stringのanalyzed設定に関しては実際のマッピングを以下のコマンドで確認すればOKです。

$ curl -X GET http://localhost:9200/logstash-xxxx

date型で想定通りに検索できるかどうかは以下で確認します。

$ curl -X POST http://localhost:9200/logstash-xxxx/idle/_search -H "Content-type: application/json" -d '{
  "query": {
    "range": {
      "created_at": {
        "from": "Sat Mar 12 00:07:23 +000 2016",
        "to": "Sat Mar 12 00:07:23 +0000 2016"
      }
    }
  }
}'

既存のインデックスのsettingsを変更する方法

以下のコマンドで既存のインデックスのsettings(アナライザなど)を変更することができます。
$ curl -X POST localhost:9200/logstash-2016.03.12/_close
$ curl -X PUT localhost:9200/logstash-2016.03.12/_settings -d '{
  "analysis": {
    "filter": {
      "pos_filter": {
        "type": "kuromoji_part_of_speech",
        "stoptags": [
          "接続詞",
          ...
        ]
      }
    },
    "tokenizer": {
      "ja_tokenizer": {
        "type": "kuromoji_tokenizer",
        "mode": "search",
        "user_dictionary": "userdict_ja.txt"
      }
    },
    "analyzer": {
      "ja_analyzer": {
        "type": "custom",
        "tokenizer": "ja_tokenizer",
        "filter": [
          "pos_filter"
        ]
      }
    }
  }
}'
$ curl -X POST localhost:9200/logstash-2016.03.12/_open

参考URL:Update Indices Settings

ドキュメントのトークンを見る方法

{elastic search path}/config/elasticsearch.ymlで以下の記述を追加します。
script.engine.groovy.inline.search: on

あとは以下のコマンドでドキュメントのトークンを確認できます。

$ curl 'http://localhost:9200/logstash-2016.03.12/_search?pretty=true' -d '{
  "query": {
    "match_all": {}
  },
  "script_fields": {
    "terms": {
      "script": "doc[field].values",
      "params": {
        "field": "text"
      }
    }
  }
}'

ElasticSearch用のfluentd設定

utc_indexをfalseにするとマシンのローカルタイムでインデックスが作成されます(インデックスのYYYYMMDDのところ)。@timestampフィールドはデフォルトでElasticSearchにデータを流し込むタイミングになりますが、ツイッターの場合はcreated_atを利用した方がイベント発生時刻としては正確です。その場合はtime_keyにcreated_atを設定します。ただし、そのままだとインデックスで利用するタイムスタンプとして解釈できなくなるので、time_key_formatを適切に設定する必要があります。
@type elasticsearch
host localhost
port 9200
type_name idle
logstash_format true
utc_index false
time_key created_at
time_key_format %a %b %d %H:%M:%S %z %Y
このエントリーをはてなブックマークに追加