概要
Elasticsearchのサジェスト機能を使って、電話番号のような数字の羅列をAutoCompleteさせようとしたときに詰まったところの備忘録がてらにご紹介。
soft | version |
---|---|
Elasticsearch | 6.3.2 |
Kibana | 6.3.2 |
使うもの
- Completion Suggester
嵌りポイント
公式のドキュメントを写経しても、電話番号のような文字列を入れたときには、期待した結果が得られない。
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のところには、こんな記述があります。
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を選びなさい、ってことですな。