Edited at

Elasticsearchで電話番号をAutoCompleteさせる

More than 1 year has passed since last update.


概要

Elasticsearchのサジェスト機能を使って、電話番号のような数字の羅列をAutoCompleteさせようとしたときに詰まったところの備忘録がてらにご紹介。

soft
version

Elasticsearch
6.3.2

Kibana
6.3.2


使うもの


  • Completion Suggester

https://www.elastic.co/guide/en/elasticsearch/reference/current/search-suggesters-completion.html


嵌りポイント

公式のドキュメントを写経しても、電話番号のような文字列を入れたときには、期待した結果が得られない。

PUT music

{
"mappings": {
"_doc" : {
"properties" : {
"suggest" : {
"type" : "completion"
},
"title" : {
"type": "keyword"
}
}
}
},
"settings": {
"number_of_shards": 1,
"number_of_replicas": 0
}
}
POST music/_doc/1?refresh
{
"suggest" : {
"input": [ "Nevermind", "Nirvana" ],
"weight" : 34
}
}

POST music/_doc/2?refresh
{
"suggest" : {
"input": [ "aiueo", "0120444449" ],
"weight" : 30
}
}

と、このようにデータを用意します。

本家のドキュメント、ほぼそのままです。

POST music/_search

{
"suggest": {
"song-suggest" : {
"prefix" : "Nir",
"completion" : {
"field" : "suggest"
}
}
}
}

これだと、サジェスト結果が得られますが、下のほうにprefixで0120といれたときは、結果が得られません。

0120で始まるデータ(id=2)のデータがヒットして欲しいと思っています。

POST music/_search

{
"suggest": {
"song-suggest" : {
"prefix" : "0120",
"completion" : {
"field" : "suggest"
}
}
}
}


何が良くないのか

困ったときは、公式のドキュメントをググるか、discussやGithubのissueを見るのが手っ取り早いです。

そうしますと、良い感じのものが既に投稿されていますね。

Completion Suggester : Support for numeric value completion suggestion


The default analyzer used in the completion suggester is the simple one,

which strips out numbers.


デフォルトのAnalyzer(=simple)だと、数字はstripされるよ、と。

なので、通常の文字列は問題なく動作したのに、数字の羅列のような電話番号だと、サジェストされなかった、ということですな。


じゃあ、どうするか

analyzerをsimpleでなく、例えばstandardなどを選びます。

(このあたりは、discussにもあるように、ユースケースに応じて選ぶべきでしょう)

PUT music

{
"mappings": {
"_doc" : {
"properties" : {
"suggest" : {
"type" : "completion",
"analyzer": "standard"
},
"title" : {
"type": "keyword"
}
}
}
}
, "settings": {
"number_of_shards": 1,
"number_of_replicas": 0
}
}

このように、マッピングを作り直して、再度クエリを投げてみます。

おおお、サジェスト結果が得られましたね!!!


ドキュメントを再度見る

で、再度ドキュメントを確認しますと、analyzerのところには、こんな記述があります。

https://www.elastic.co/guide/en/elasticsearch/reference/current/search-suggesters-completion.html


In case you are wondering why we did not opt for the standard analyzer: We try to have easy to understand behaviour here


理解を容易にするためstandardじゃなくてsimple analyzerにしてるよ、とちゃんと書いてありました。

入る値、どういう検索をしたいのかを考慮してanalyzerを選びなさい、ってことですな。