Запрос match - это основной запрос, используемый для полнотекстовых запросов, включая запросы с нечетким соответствием, в то время как запрос match_phrase, хотя и похож, учитывает близость слов. Запрос multi_match предлагает упрощенный синтаксис для запросов match и match_phrase по нескольким полям.
Запросы match работают с анализируемым текстом, поэтому результаты зависят от анализаторов, которые были определены для разбиения текста на лексемы (обычно слова). Анализаторы обычно определяются в связках индексов.
Запрос на совпадение
Запрос match возвращает документы, соответствующие определенному набору искомых лексем, которые могут быть текстами, числами, датами или булевыми значениями. Запрос match, имеющий опции нечеткого сопоставления, является стандартным запросом, используемым для выполнения полнотекстового поиска.
Ниже приведены две эквивалентные структуры для выполнения запроса на соответствие:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | GET index/_search { "query": { "match": { "<field>": "The value that needs to be found in the provided field" } } } GET index/_search { "query": { "match": { "<field>": { "query": "The value that needs to be found in the provided field" } } } } |
<field> представляет собой поле, в котором вы хотите выполнить поиск.
Если пользователям необходимо добавить в запрос любой из следующих параметров, следует использовать второй синтаксис.
Ниже приведены параметры запроса на соответствие:
- Query (запрос): Необходимый параметр, который может представлять собой текст, число, логическое значение или дату, которые пользователи ищут в указанном поле.
- Analyzer (Анализатор): Необязательный параметр типа string, определяющий анализатор, который будет преобразовывать текст запроса в лексемы. По умолчанию используется индексный анализатор, сопоставленный для <поля>.
- Auto_generate_synonyms_phrase_query: Необязательный параметр типа boolean. Если он равен true, то многотерминальные запросы на совпадение синонимов с фразами создаются автоматически. Это важно только в том случае, если индекс использует фильтр маркеров графов. По умолчанию используется значение True.
- Fuzziness (нечеткость): Необязательный параметр типа string, представляющий наибольшее расстояние редактирования, допустимое для соответствия. Расстояние редактирования - это расчет, используемый для определения того, насколько похожи две строки. Расстояние редактирования между двумя строками вычисляется путем подсчета количества односимвольных правок (вставок, удалений или замен), необходимых для преобразования одной строки в другую. Меньшее расстояние редактирования указывает на большее сходство между двумя строками. Например, для превращения "lisence" в "license" требуется 2 правки, что соответствует расстоянию правки 2. Используйте число (1,2) или используйте "auto", чтобы обеспечить переменную нечеткость в зависимости от длины слова.
- Max_expansion: Необязательный параметр типа integer, представляющий максимальное количество терминов, на которые будет расширен запрос. Это важно для нечеткого поиска, который переписывает запрос в число терминов, зависящее от параметров нечеткости. Чем больше терминов используется, тем выше нагрузка на кластер. Значение по умолчанию - 50.
- Prefix_length: Необязательный параметр типа integer, который показывает, сколько начальных символов было оставлено неизменными для нечеткого соответствия. По умолчанию значение равно 0. Логика заключается в том, что орфографические ошибки обычно не встречаются в начале слова, поэтому добавление prefix_length делает нечеткие запросы более эффективными.
- Fuzzy_transpositions: Необязательный параметр типа boolean. Если параметр равен true, то редактирование для нечеткого соответствия может включать транспонирование двух соседних символов (ab → ba). В этом случае 2 правки считаются за 1. Значение по умолчанию - true.
- Fuzzy_rewrite: Необязательный параметр типа string, который представляет метод, используемый для перезаписи запроса. По умолчанию в запросе match используется метод fuzzy_rewrite из top_terms_blended_freqs_${max_expansions}, если параметр fuzziness не равен 0.
- Lenient: Необязательный параметр типа boolean. Если параметр равен true, то ошибки, связанные с форматом, игнорируются, например ввод текстового значения запроса для числового поля. Значение по умолчанию - false.
- Operator (Оператор): Необязательный параметр типа string, который представляет булеву логику, используемую при интерпретации текста в значении запроса. Имеет два допустимых значения: OR и AND, где OR - значение по умолчанию.
- Minimum_should_match: Необязательный параметр типа string, который представляет собой минимальное количество совпадающих пунктов для возврата документа. Этот параметр должен использоваться только с оператором "ИЛИ" и является более гибким, чем простое "и/или", поскольку пользователи могут устанавливать правила в зависимости от длины фразы, которая должна быть сопоставлена.
75% (например, 3 из 4 слов, подлежащих подбору, или 6 из 8)
2 (минимум 2 слова, которые должны быть найдены, независимо от длины строки) - Zero_terms_query: Необязательный параметр типа string. При использовании стоп-фильтра, например, это значение указывает, будут ли возвращены документы, если анализатор удалит все лексемы. Имеет два значения: none и all. Значение по умолчанию none указывает на то, что если анализатор удаляет все лексемы (например, в запросе "the" с использованием анализатора английского языка), то ни один документ не будет возвращен.
1 2 3 4 5 6 7 8 9 10 11 | GET books/_search { "query": { "match": { "title": { "query": "OpenSearch Observability", "operator": "or" } } } } |
Приведенный выше запрос будет соответствовать документам, содержащим ИЛИ OpenSearch ИЛИ Observability.
Чтобы повысить точность предыдущего запроса, измените логику "или" в запросе на "и" с помощью параметра "оператор", как показано в примере ниже. Таким образом, в поиск попадут только те документы, у которых в поле "заголовок" присутствуют оба слова "OpenSearch и Observability".
В следующем примере добавьте параметр "нечеткость", разрешающий не более 2 правок на слово, что приводит к увеличению количества возвращаемых совпадений, изменяя при этом релевантность результатов.
1 2 3 4 5 6 7 8 9 10 11 12 | GET books/_search { "query": { "match": { "title": { "query": "OpenSearch Observability", "fuzziness": 2, "operator": "and" } } } } |
Используя приведенный выше запрос, вы получите следующее:
- Observability на основе OpenSearch
- observability based on OpenSearch
- observability of OpenSearch (из-за нечеткого поиска)
Просто "OpenSearch" сам по себе не будет соответствовать (из-за оператора and).
Запрос на совпадение фраз
Запрос match_phrase учитывает близость слов, требуя, чтобы слова были найдены в пределах настраиваемого "уклона" или расстояния. Пример ниже - запрос match_phrase, который ищет в книжном индексе книги с фразой "OpenSearch Observability" в названии.
1 2 3 4 5 6 7 8 | GET books/_search { "query": { "match_phrase": { "title": "OpenSearch Observability" } } } |
Фразовый запрос сопоставляет слова в любой последовательности в пределах настраиваемого наклона (по умолчанию значение равно 0). Например:
1 2 3 4 5 6 7 8 9 10 11 | GET books/_search { "query": { "match_phrase": { "title": { "query": "OpenSearch Observability", "slop": 1 } } } } |
Все вышеперечисленное совпадает:
- OpenSearch observability
- OpenSearch system observability (потому что мы настроили slop равным 1)
Не будет соответствовать: OpenSearch system downtime observability
Как упоминалось в запросе match, в этом запросе также используется параметр zero_terms_query
Нечеткий поиск нельзя использовать с фразовыми соответствиями.
Многовариантный запрос
Для выполнения запросов по нескольким полям на основе запроса match строится запрос multi_match. Книга может очень подробно обсуждать наблюдаемость OpenSearch и не иметь слова "OpenSearch observability" в названии, поэтому поиск только по одному полю не является лучшим подходом для данного примера. В приведенном ниже примере используется запрос multi_match, который ищет "наблюдаемость OpenSearch" и в названии, и в аннотации. Запрос multi_match дает гораздо больше совпадений, чем запросы match и match_phase только по полю заголовка, при этом лучшие совпадения сохраняют свою релевантность.
1 2 3 4 5 6 7 8 9 10 11 12 | GET books/_search { "query": { "multi_match": { "query": "OpenSearch Observability", "fields": [ "title", "abstract" ] } } } |
Для указания полей можно использовать подстановочные знаки, как показано в примере ниже: будут запрошены поля book_title, first_name и last_name.
1 2 3 4 5 6 7 8 9 | GET authors/_search { "query": { "multi_match" : { "query": "Elie Smith", "fields": [ "book_title", "*_name" ] } } } |
Каретка (^) может использоваться для повышения оценок конкретных полей. В следующем примере поле "Заголовок" получает прибавку в 2 балла.
1 2 3 4 5 6 7 8 9 10 11 12 | GET books/_search { "query": { "multi_match": { "query": "OpenSearch Observability", "fields": [ "title^2", "abstract" ] } } } |
Если поля не указаны, multi match_query по умолчанию использует настройки индекса index.query.default_field, который, в свою очередь, по умолчанию *. * извлекает из отображения все поля, которые подходят для запросов терминов, в дополнение к фильтрации полей метаданных. Затем создается запрос, объединяющий все извлеченные поля.
Параметр type, который имеет следующие варианты, определяет, как будет выполняться запрос multi_match:
Best_fields: По умолчанию означает поиск документов, соответствующих любому полю, используя оценку по полю с наивысшей оценкой. При поиске нескольких слов, которые лучше всего искать в одном поле, наиболее полезен тип best_fields. Как показано в примере ниже, "OpenSearch Observability" в одном поле более релевантно, чем "OpenSearch" в одном поле и "Observability" в другом поле.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | GET books/_search { "query": { "multi_match": { "query": "OpenSearch Observability", "type": "best_fields", "fields": [ "title", "abstract" ], "tie_breaker": 0.3 } } } |
Он принимает следующие параметры: analyzer, boost, operator, minimum_should_match, fuzziness, lenient, prefix_length, max_expansion, fuzzy_rewrite, zero_terms_query, auto_generate_synonyms_phrase_query и fuzzy_transpositions, которые были объяснены в запросе match.
Most_fields: Комбинирует _score каждого поля, чтобы найти документы, соответствующие любому полю. При поиске по многим полям, содержащим одинаковый текст, но проанализированным по-разному, наиболее полезен тип most_fields.
Как показано в примере ниже, основное поле может включать стемминг, синонимы и термины без диакритических знаков. Оригинальные термины могут находиться во втором поле, а черепица - в третьем. Наиболее похожие результаты продвигаются в верхнюю часть списка с помощью второго и третьего полей, объединяя оценки трех полей, что позволяет сопоставить как можно больше документов с первичным полем.
1 2 3 4 5 6 7 8 9 10 | GET books/_search { "query": { "multi_match" : { "query": "data mining", "type": "most_fields", "fields": [ "title","title.shingles", "title.original" ] } } } |
Суммарный балл всех совпадающих клаузул делится на общее количество совпадающих клаузул. В типе most_fields принимаются следующие параметры, описанные ранее: analyzer, boost, operator, minimum_should_match, fuzziness, lenient, prefix_length, max_expansion, fuzzy_rewrite и zero_terms_query.
Cross_fields: Все поля с одним и тем же анализатором должны рассматриваться как одно большое поле. Этот запрос ищет каждое слово в каждом поле. При работе со структурированными документами, в которых требуется совпадение многих полей, тип cross_fields очень полезен. Например, наилучшее совпадение при поиске "Elie Smith", скорее всего, включает "Elie " в поле first_name и "Smith" в поле last_name.
1 2 3 4 5 6 7 8 9 10 11 | GET authors/_search { "query": { "multi_match" : { "query": "Elie Smith", "type": "cross_fields", "fields": [ "first_name", "last_name" ], "operator": "and" } } } |
В типе cross_field принимаются следующие параметры, описанные ранее: analyzer, boost, operator, minimum_should_match, lenient и zero_terms_query.
Phrase: Использует _score лучшего поля после выполнения запроса match_phrase для каждого поля.
Phrase_prefix: Использует _оценку лучшего поля после выполнения запроса с префиксом_фразы для каждого поля. При использовании запроса match_phrase или match_phrase_prefix вместо запроса match типы phrase и phrase_prefix работают точно так же, как best_fields.
1 2 3 4 5 6 7 8 9 10 11 12 13 | GET books/_search { "query": { "multi_match": { "query": "OpenSearch Observability", "type": "phrase_prefix", "fields": [ "title", "abstract" ] } } } |
Bool_prefix: Комбинирует _score из каждого поля и выполняет запрос match_bool_prefix для каждого поля. Оценка типа bool_prefix ведет себя аналогично оценке типа most_fields, используя запрос match_bool_prefix вместо запроса match.
1 2 3 4 5 6 7 8 9 10 11 12 13 | GET books/_search { "query": { "multi_match": { "query": "OpenSearch Observability", "type": "bool_prefix", "fields": [ "title", "abstract" ] } } } |
Поддерживаются следующие параметры: analyzer, boost, operator, minimum_should_match, lenient, zero_terms_query и auto_generate_synonyms_phrase_query.
Для терминов, используемых для построения терминологических запросов, поддерживаются параметры fuzziness, prefix_length, max_expansions, fuzzy_rewrite и fuzzy_transpositions, однако они не влияют на префиксный запрос, построенный из конечного термина. Кроме того, этот тип запроса не поддерживает параметр slop.
Нельзя использовать нечеткий поиск с фразовым соответствием.
Примечания и полезные советы
- Термины с синонимами и ситуации, в которых процесс анализа генерирует несколько лексем в одном и том же месте, не подлежат нечеткому сопоставлению. Такие термины расширяются внутри системы до специальных запросов с синонимами, которые объединяют частоты терминов и не поддерживают нечеткое расширение.
- По умолчанию запрос имеет только ограниченное количество клаузул. Это ограничение задается параметром indices.query.bool.max_clause_count, значение которого по умолчанию равно 4096. Количество клаузул для мультиматчевых запросов определяется умножением количества полей на количество терминов.
- В мультиматчевом запросе типы best_fields и most_fields создают запрос на совпадение для каждого поля, что делает их ориентированными на поля. В результате параметры minimum_should_match и operator будут применяться к каждому полю независимо, а это, скорее всего, не то, что вам нужно. Метод, ориентированный на термин, обеспечивается запросом combined_fields, который обрабатывает оператор и minimum_should_match на основе каждого термина. Перекрестные поля, другой тип мультиматча, аналогично решают эту проблему.
- В запросе multi-match пользователи не могут использовать параметр fuzziness с типами phrase, phrase_prefix и cross_fields.
- Тип cross_fields объединяет статистику полей таким образом, что иногда получаются не совсем корректно сформированные оценки (например, оценки могут стать отрицательными). В качестве альтернативы стоит рассмотреть запрос combined_fields, который также ориентирован на термины, но более надежно объединяет статистику полей.
- Помните, что тип cross_fields в запросе multi-match обычно полезен только для коротких строковых полей с boosts, равным 1. В противном случае на оценку влияют boosts, частоты терминов и нормализация длины, что делает комбинацию статистики терминов бессмысленной.
Заключение
"Match", "Multi-Match" и "Match Phrase" - это все типы запросов в OpenSearch, используемые для поиска совпадающих документов в индексе.
- Match Query: Запрос на совпадение используется для поиска документов, содержащих один или несколько определенных терминов. Он допускает частичное совпадение и автоматически применяет базовый анализ текста к строке запроса, чтобы сгенерировать набор терминов для поиска.
- Multi-Match Query: Запрос с несколькими совпадениями используется для поиска документов, содержащих один или несколько определенных терминов в нескольких полях. Этот запрос полезен, если у вас есть несколько полей для поиска, и вы хотите использовать один и тот же запрос для каждого поля.
- Match Phrase Query: Запрос по фразе используется для поиска документов, содержащих точную фразу. Он соответствует полной фразе, включая порядок следования терминов, в том виде, в котором она встречается в документе. В отличие от запроса "match", запрос "match phrase" не допускает частичного совпадения.
С точки зрения производительности запрос на совпадение обычно быстрее, чем запрос на совпадение фраз, поскольку он может использовать инвертированный индекс для быстрого определения совпадающих документов. Запрос с несколькими совпадениями обычно работает медленнее, чем запрос с совпадениями, поскольку ему приходится искать по нескольким полям, но он может давать более полные результаты.