Эластичный поиск с фонетическим поиском
Я пытаюсь заставить Elastic Search выполнять фонетический поиск в списке городов. Моя цель - найти совпадающие результаты, даже если пользователь использует неправильное написание.
Я сделал следующие шаги:
Удалить домен
curl -X DELETE "localhost:9200/city/"
Создать новый домен
curl -X PUT "localhost:9200/city/?pretty" -H 'Content-Type: application/json' -d' { "settings": { "index": { "analysis": { "analyzer": { "my_analyzer": { "tokenizer": "standard", "filter": [ "lowercase", "my_metaphone" ] } }, "filter": { "my_metaphone": { "type": "phonetic", "encoder": "metaphone", "replace": true } } } } }, "mappings": { "properties": { "name": { "type": "text", "analyzer": "my_analyzer" } } } }'
Заполните образцы данных
curl -X PUT "localhost:9200/city/_doc/1?pretty" -H 'Content-Type: application/json' -d' { "name":"Mayrhofen" } ' curl -X PUT "localhost:9200/city/_doc/2?pretty" -H 'Content-Type: application/json' -d' { "name":"Ischgl" } ' curl -X PUT "localhost:9200/city/_doc/3?pretty" -H 'Content-Type: application/json' -d' { "name":"Saalbach" } '
Искать по городам - вот и результат
curl -X GET ""localhost:9200/city/_search?pretty" -H 'Content-Type: application/json' -d' { "query":{ "query_string":{ "query":"Mayrhofen" } } } '
Я попробовал выполнить запрос с Майерхофеном и ожидал того же результата, что и с Майрхофеном. Та же проблема с Ишгль и Ichgl или Заальбах и Salbach.
Где моя ошибка? Что-то не так?
1 ответ
Проблема в том, что вы используете неправильный encoder
. metaphone
не может соответствовать этим.
Вам нужно использовать double_metaphone
для ваших входов. Он основан на реализации фонетического алгоритма. Я бы посоветовал вам понять свои данные и алгоритм, чтобы убедиться, что фонетический алгоритм лучше всего подходит для ваших целей.
Отображение:
{
"analysis": {
"analyzer": {
"double_meta_true_analyzer": {
"tokenizer": "standard",
"filter": [
"lowercase",
"true_doublemetaphone"
]
}
},
"filter": {
"true_doublemetaphone": {
"type": "phonetic",
"encoder": "double_metaphone",
"replace": true
}
}
}
}
Он соответствует документам.
Почему метафон не совпадает:
GET http://localhost:9200/city2/_analyze
{
"field":"meta_true",
"text":"Mayrhofen"
}
дает
{
"tokens": [
{
"token": "MRHF",
"start_offset": 0,
"end_offset": 9,
"type": "<ALPHANUM>",
"position": 0
}
]
}
И анализируя ниже
{
"field":"meta_true",
"text":"Mayerhofen"
}
дает
{
"tokens": [
{
"token": "MYRH",
"start_offset": 0,
"end_offset": 10,
"type": "<ALPHANUM>",
"position": 0
}
]
}
Double_Metaphone работает следующим образом:
GET
{
"field":"doublemeta_true",
"text":"Mayerhofen"
}
А также
{
"field":"doublemeta_true",
"text":"Mayerhofen"
}
а также
{
"field":"doublemeta_true",
"text":"Mayrhofen"
}
дает
{
"tokens": [
{
"token": "MRFN",
"start_offset": 0,
"end_offset": 10,
"type": "<ALPHANUM>",
"position": 0
}
]
}