Фразовые и групповые запросы на Elasticsearch - PullRequest
0 голосов
/ 27 февраля 2019

Я сталкиваюсь с некоторыми трудностями при попытке создать запрос, который может соответствовать только целым фразам, но также допускает использование подстановочных знаков.

В основном у меня есть поле, содержащее строку (фактически это список строк, но для простоты я пропускаю это), которое может содержать пробелы или быть нулевым, давайте назовем это «цветом».

Например:

{
  ...
  "color": "Dull carmine pink"
  ...
}

Мои запросы должны быть в состояниисделать следующее:

  • поиск значений NULL (включительно и эксклюзивно)
  • поиск значений NULL (включительно и исключительно)
  • поиск и совпадение толькоцелая фраза (включительно и эксклюзивно).Например:
    • тусклый карминно-розовый -> совпадение
    • карминно-розовый -> не совпадение
  • то же, что и в прошлом, но с подстановочными знаками(включительно и эксклюзивно).Например:
    • полный кармин p * -> соответствует «тусклый кармин розовый»
    • тусклый кармин * -> соответствует «тусклый кармин розовый»
    • и т. Д.

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

Мне удалось лишь частично заставить его работать с запросом span_near с помощью этой темы .

Так что теперь я могу:

  • искать целую фразу с / без подстановочных знаков, как это:

    {
        "span_near": {
            "clauses": [
                {
                    "span_term": {"color": "dull"}
                },
                {
                    "span_term": {"color": "carmine"}
                },
                {
                    "span_multi": {"match": {"wildcard": {"color": "p*"}}}
                }
            ],
            "slop": 0,
            "in_order": true
        }
    }
    
  • поиск нулевых значений (включительно и эксклюзивно) с помощью простых запросов must / must_not, таких как:

    {
       "must" / "must_not": {'exist': {'field': 'color'}}
    }
    

Проблема: Я не могу найти способ сделать эксклюзивный запрос по диапазону.Единственный способ найти это это .Но для этого требуются поля include и exclude, а я только пытаюсь исключить некоторые поля, все остальные должны быть возвращены.Есть ли какой-нибудь аналог запроса "match_all": {}, который может работать внутри поля включения span_not?Или, может быть, совершенно новое, более элегантное решение?

1 Ответ

0 голосов
/ 10 апреля 2019

Я нашел решение месяц назад, но забыл опубликовать его здесь.У меня нет под рукой примера, но я попытаюсь объяснить его.

Проблема заключалась в том, что поля, которые я пытался запросить, были проанализированы с помощьювалайзера поиска до запроса.Рассматриваемый анализатор делил их на пробелы и т. Д. Решение этой проблемы является одним из двух:

1. Если вы не используете настраиваемое сопоставление для индекса.

(Имеется в виду, если вы позволили эластичному поиску динамически создавать соответствующее отображение для вашего поля при его добавлении).

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

Это означает, что такие запросы, как:

{
"query": {
    "bool": {
        "must": [ // must_not
            {
                "match": {
                    "user.keyword": "Kim Chy"
                }
            }
        ]
    }
}

} и

{
"query": {
    "bool": {
        "must": [ // must_not
            {
                "wildcard": {
                    "user.keyword": "Kim*y"
                }
            }
        ]
    }
}

}

должны работать как положено.

Однако при сопоставлении по умолчанию поле ключевого слова, скорее всего, будет чувствительным к регистру.Для того, чтобы он также не учитывал регистр, вам необходимо создать собственное отображение, которое применяет строчные (или прописные) normalizer к полю запроса и ключевого слова перед сопоставлением.

2.Если вы используете настраиваемое сопоставление

По сути то же самое, что и выше, однако вам придется создать новое подполе (или поле) вручную, которое использует анализатор ключевых слов (и, возможно, нормализатор, чтобы онбыть нечувствительным к регистру).

PS Насколько я знаю, изменение отображения больше невозможно в эластичном поиске.Это означает, что вам придется создать новый индекс с соответствующим отображением, а затем переиндексировать данные в новый индекс.

...