Эластичный поиск с фонетическим поиском

Я пытаюсь заставить Elastic Search выполнять фонетический поиск в списке городов. Моя цель - найти совпадающие результаты, даже если пользователь использует неправильное написание.

Я сделал следующие шаги:

  1. Удалить домен

    curl -X DELETE "localhost:9200/city/"
    
  2. Создать новый домен

    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"
          }
        }
      }
    }'
    
  3. Заполните образцы данных

    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"
    }
    '
    
  4. Искать по городам - ​​вот и результат

    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
        }
    ]
}
Другие вопросы по тегам