Elasticsearchにメールアドレスを放り込む際、どうもサブドメイン等でSearchを行う際にうまく検索ができないことがあった。 そもそもElasticsearchの検索の仕組みをよく理解できてなかったのもあるのだが、ドキュメント作成時にAnalyzerで分割した文字単位で検索を行うようだ。 で、その差異にデフォルトのAnalyzerではうまくメールアドレスの分割ができていなかったのが原因のようだ。
Elasticsearchでは、以下のようにリクエストを投げることでAnalyzerでどのように分割されるのかを見ることができるので、それでメールアドレスがどのように分割されるのか見てみよう。
まず、新規で追加するAnalyzerは以下のjsonで作成できるので、これを適当なファイル名(ここではdomain_analyzer.json)でファイルを作成しよう。
{
"analysis": {
"analyzer": {
"domain_analyzer": {
"filter":"lowercase",
"tokenizer": "domain_tokenizer",
"type": "custom"
}
},
"tokenizer": {
"domain_tokenizer": {
"type": "PathHierarchy",
"delimiter": ".",
"reverse": true
}
}
}
}
ファイルを作成したら、以下のコマンドで既存のINDEXにAnalyzerを追加する。
curl -XPUT 'localhost:9200/INDEX名/_mapping/TYPE名' -d @domain_analyzer.json
これで、指定したINDEXにAnalyzerの追加ができたはずだ。 以下のコマンドで、追加したAnalyzerがどのようにパースするのかが確認できる。
curl 'localhost:9200/INDEX名/_analyze?analyzer=domain_analyzer&pretty' -d 'xxx-ddd.test.co.jp'
test@test-es:~$ curl 'localhost:9200/test/_analyze?analyzer=domain_analyzer&pretty' -d 'xxx-ddd.test.co.jp'
{
"tokens" : [
{
"token" : "xxx-ddd.test.co.jp",
"start_offset" : 0,
"end_offset" : 18,
"type" : "word",
"position" : 0
},
{
"token" : "test.co.jp",
"start_offset" : 8,
"end_offset" : 18,
"type" : "word",
"position" : 0
},
{
"token" : "co.jp",
"start_offset" : 13,
"end_offset" : 18,
"type" : "word",
"position" : 0
},
{
"token" : "jp",
"start_offset" : 16,
"end_offset" : 18,
"type" : "word",
"position" : 0
}
]
}
あとは、mappingで特定のフィールドにAnalyzerを追加してやればいいだろう。 既存のデータに対しては、後からフィールドにAnalyzerを追加しても意味がないようなので、インデックス化を再度やり直したほうがいいようだ。