MacにElasticSearchを入れてanalyzerでスプリットして検索する

書いてる理由

  • ElasticSearchでなんらかのセパレータで区切られているレコードを検索したい。

やったこと

ElasticSearchにセパレータでスプリットするカラム定義を記述してデータを投入して検索。

参考

www.elastic.co

詳細

以下の手順でできた。

# settingでtest1にインデックスを貼る。mappingでカラム定義をする。
curl -H 'Content-Type: application/json' -XPUT 'localhost:9200/test1?pretty' -d '
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_analyzer": {
          "tokenizer": "my_tokenizer"
        }
      },
      "tokenizer": {
        "my_tokenizer": {
          "type": "pattern",
          "pattern": ","
        }
      }
    }
  },
  "mappings": {
    "test1": {
      "properties": {
        "field1": {"type": "text", "analyzer": "my_analyzer"}
      }
    }
  }
}'
# or 
curl -H 'Content-Type: application/json' -XPUT 'localhost:9200/test1?pretty'  --data-binary @schema.json  # schema.json は上と同じもの

# 貼ったインデックスのアナライザーの確認
curl -H 'Content-Type: application/json' -XPOST 'localhost:9200/test1/_analyze?pretty' -d'
{
  "field": "field1",
  "text": ",12,13,14,"
}'
>{
>  "tokens" : [
>    {
>      "token" : "12",
>      "start_offset" : 1,
>      "end_offset" : 3,
>      "type" : "word",
>      "position" : 0
>    },
>    {
>      "token" : "13",
>      "start_offset" : 4,
>      "end_offset" : 6,
>      "type" : "word",
>      "position" : 1
>    },
>    {
>      "token" : "14",
>      "start_offset" : 7,
>      "end_offset" : 9,
>      "type" : "word",
>      "position" : 2
>    }
>  ]
>}
# tokenが別れていて、検索対象として,でちゃんと値が別れていることがみて取れる。

# データ投入
curl -H 'Content-Type: application/json' -XPOST 'localhost:9200/test1/test1/_bulk?pretty' --data-binary @data.json
cat data.json
{ "index" : {}       }
{ "field1"  : "12,13,14"   }
{ "index" : {}       }
{ "field1"  : ",09809,12," }
{ "index" : {}       }
{ "field1"  : "13"   }
{ "index" : {}       }
{ "field1"  : "11,13,14" }
{ "index" : {}       }
{ "field1"  : "12,13"   }
{ "index" : {}       }
{ "field1"  : "11," }
# 13を含むレコードが4個、合計6個のデータを投入

# field1に「13」を含むレコードを検索
curl -H 'Content-Type: application/json' -XPOST 'localhost:9200/test1/test1/_search?pretty' -d '
{
 "_source": ["field1"],
 "query":{
  "bool": {
   "must": [{
    "term" : {"field1": "13"}
   }]
  }
 }
}'
{
  "took" : 50,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 4,
    "max_score" : 1.0925692,
    "hits" : [
      {
        "_index" : "test1",
        "_type" : "test1",
        "_id" : "9AjFqnABwtT4P6khbXNW",
        "_score" : 1.0925692,
        "_source" : {
          "field1" : "13"
        }
      },
      {
        "_index" : "test1",
        "_type" : "test1",
        "_id" : "9QjFqnABwtT4P6khbXNW",
        "_score" : 0.2876821,
        "_source" : {
          "field1" : "11,13,14"
        }
      },
      {
        "_index" : "test1",
        "_type" : "test1",
        "_id" : "8gjFqnABwtT4P6khbXNW",
        "_score" : 0.2876821,
        "_source" : {
          "field1" : "12,13,14"
        }
      },
      {
        "_index" : "test1",
        "_type" : "test1",
        "_id" : "9gjFqnABwtT4P6khbXNW",
        "_score" : 0.2876821,
        "_source" : {
          "field1" : "12,13"
        }
      }
    ]
  }
}
# 13を含んだやつだけ取得できてる!

感想

よかったできた。。 アナライザーは形態素解析系のものはたくさん情報があるけど、シンプルなやつはあんまり情報がないからちょっと手間取った。。