Нечеткий поиск в ElasticSearch не работает с пробелами - PullRequest
2 голосов
/ 27 октября 2019

Я использую опцию нечеткого поиска в ElasticSearch. Это довольно круто.

Но я столкнулся с проблемой при поиске значений с пробелами. Например, скажем, у меня есть два значения:

"Pizza"
"Pineapple Pizza"

, и я ищу Пиццу по этому запросу:

        client.search({
            index: 'food_index',
            body: {
                query: {
                    fuzzy: {
                        name: {
                            value: "Pizza",
                            transpositions: true,
                        }
                    },
                }
            }
        })

Возвращаются следующие значения:

"Pizza"
"Pineapple Pizza"

Какиеожидается. Но если я введу в запросе значение «Ананасовая пицца»:

        client.search({
            index: 'food_index',
            body: {
                query: {
                    fuzzy: {
                        name: {
                            value: "Pineapple Pizza",
                            transpositions: true,
                        }
                    },
                }
            }
        })

Вернутся следующие значения:

""

Пусто

Почему это так? Это должно быть точное совпадение. Я обдумываю переключение всех имен, в которых есть пробелы, на подчеркивание. Таким образом, «Pineapple Pizza» будет «Pineapple_Pizza» (это решение работает для меня). Но я задаю этот вопрос, чтобы надеяться найти лучшую альтернативу. Что я тут не так делаю?

1 Ответ

2 голосов
/ 27 октября 2019

Нечеткие запросы - это запросы уровня термина. Это означает, что искомый текст не анализируется перед сопоставлением документов. В вашем случае используется стандартный анализатор имени поля, который разделяет «Pineapple Pizza» на два жетона: Pineapple и pizza. Нечеткий запрос пытается сопоставить поисковый текст «Ананасовая пицца» с любым подобным термином в индексе, и в индексе отсутствует запись для всего слова «ананасовая пицца» (она разбита на два слова.)

Вам необходимо использовать соответствие запроса с нечеткостью, установленной для анализа строки запроса

{
  "query": {
        "match" : {
            "item" : {
                "query" : "Pineappl piz",
                "fuzziness": "auto"
            }
        }
    }
}

Ответ:

 [
      {
        "_index" : "index27",
        "_type" : "_doc",
        "_id" : "p9qQDG4BLLIhDvFGnTMX",
        "_score" : 0.53372335,
        "_source" : {
          "item" : "Pineapple Pizza"
        }
      }
    ]

Вы также можете использовать нечеткость в ключевом слове поле, котороесохраняет весь текст в индексе

{
  "query": {
    "fuzzy": {
      "item.keyword": {
        "value":"Pineapple pizz"
      }
    }
  }
}

EDIT1:

{
  "query": {
        "match" : {
            "item" : {
                "query" : "Pineapple pizza",
                "operator": "and",
                "fuzziness": "auto"
            }
        }
    }
}

"operator": "и" -> все токены в запросе должны присутствовать в документе. По умолчанию ИЛИ, если присутствует какой-либо один токен, документ присутствует. Существуют и другие возможные комбинации, в которых вы можете определить, сколько токенов должно совпадать в процентах

...