LoginSignup
3

More than 5 years have passed since last update.

elasticsearchのindexingをunderscoreで分割する

Posted at

elasticsearchのデフォルトのtokenizerは'-'や'&'では分割してくれますが,'_'では分割してくれません.つまり

"elastic-search test_data"



elastic, search, test_data

のように分割されます.これをtest, dataのようにunderscoreで分割する方法を探していました.

Word Delimiter Token Filter を使う

filterのword_delimiterでは区切り文字に関する設定を色々変えることができます.詳しくはhttps://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-word-delimiter-tokenfilter.htmlを参照してください.

このword_delimiterにあるtype_tableを使うと文字の属性(ALPHA, ALPHANUM, DIGIT, SUBWORD_DELIM等)を変えることができます.今回はunderscoreの属性をSUBWORD_DELIMに変えます.

$ curl -XPOST 'http://localhost:9200/test/' -d '
{
  "settings": {
    "analysis": {
      "filter": {
        "underscore_splitter": {
          "type": "word_delimiter",
          "type_table": [
            "_ => SUBWORD_DELIM"
          ]
        }
      },
      "analyzer": {
        "default": {
          "type": "custom",
          "tokenizer": "standard",
          "filter": [
            "lowercase",
            "underscore_splitter"
          ]
        }
      }
    }
  }
}
'

でセッテイングを登録し,analyzerの挙動を確認すると,

$ curl 'localhost:9200/test/_analyze' -d 'elastic-search test_data'
{
  "tokens": [
    {
      "token": "elastic",
      "start_offset": 0,
      "end_offset": 7,
      "type": "<ALPHANUM>",
      "position": 1
    },
    {
      "token": "search",
      "start_offset": 8,
      "end_offset": 14,
      "type": "<ALPHANUM>",
      "position": 2
    },
    {
      "token": "test",
      "start_offset": 15,
      "end_offset": 19,
      "type": "<ALPHANUM>",
      "position": 3
    },
    {
      "token": "data",
      "start_offset": 20,
      "end_offset": 24,
      "type": "<ALPHANUM>",
      "position": 4
    }
  ]
}

確かにtokenizerがunderscoreで分割しています.

おまけ: オリジナルを残す

また,word_delimiterは,preserve_originaltrueに設定することでindexingする際にオリジナルの文章を残すこともできます.

$ curl -XPOST 'http://localhost:9200/test/' -d '
{
  "settings": {
    "analysis": {
      "filter": {
        "underscore_splitter": {
          "type": "word_delimiter",
          "preserve_original": true,
          "type_table": [
            "_ => SUBWORD_DELIM"
          ]
        }
      },
      "analyzer": {
        "default": {
          "type": "custom",
          "tokenizer": "standard",
          "filter": [
            "lowercase",
            "underscore_splitter"
          ]
        }
      }
    }
  }
}
'

これにより,"elastic-search test_data"を,elastic, search, test_data, test, dataのように分割することができます.

更におまけ: Mapping Char Filter を使う

mapping char filter を使うと,indexに登録する際に文字を変換して登録することができます.詳しくはこちら

これを使って,

{
  "settings": {
    "analysis": {
      "char_filter": {
        "my_mapping": {
          "type": "mapping",
          "mappings": ["_=>-"]
        }
      },
      "analyzer": {
        "default": {
          "tokenizer": "standard",
          "char_filter": [
            "my_mapping"
          ]
        }
      }
    }
  }
}

のように無理やり'_'を'-'に変換して登録し,無理やりtest, dataと分割する方法も考えましたが,あまりに汚いので他の方法を探し,上記のやり方にたどり着きました.ただMapping Char Filter自体は色々便利そうです.

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3