OpenSearch предоставляет полный язык запросов DSL (Domain Specific Language), основанный на файлах JSON для определения запросов.
Вы можете представить DSL как абстрактное дерево синтаксиса, которое имеет два типа запросов:
- Leaf query clauses - поиск конкретного значения в определенном поле. Например, запросы типа "термин" и "совпадение". Эти запросы могут использоваться независимо друг от друга.
- Составные запросы - оборачивают другие листовые или составные запросы и используются для логического объединения нескольких запросов, например, запроса bool, или для изменения их поведения, как в запросе constant score.
Запросы на уровне терминов могут использоваться для поиска документов на основе определенных значений в структурированных данных. Структурированные данные могут включать: диапазоны дат, IP-адреса, цены, идентификаторы продуктов и т. д. Запросы на уровне терминов, в отличие от полнотекстовых запросов, не анализируют поисковые запросы, однако они соответствуют конкретным терминам, хранящимся в поле.
Существуют различные типы запросов на уровне терминов, один из которых - запрос exists. Запрос exists обеспечивает возврат документов, содержащих проиндексированное значение поля.
Рекомендуем прочитать статью о маппинге OpenSearch, которая поможет вам понять, как поля будут индексироваться в OpenSearch, а также настройки маппинга. Кроме того, вы можете прочитать о OpenSearch Search, чтобы понять, как выполняется GET API-запрос к конечной точке _search, и как мы ищем документы в индексе, что поможет вам создать основу для лучшего понимания запроса exists.
Для чего используется запрос DSL exists
Некоторые поля в документах могут не иметь индексированного значения по ряду причин. Запрос exists используется для возврата документов, имеющих индексированное значение для определенного поля, то есть он возвращает документы, в которых указанное поле существует.
Индексированное значение может не существовать в поле документа, потому что:
- Поле в исходном документе равно null или является пустым массивом (т. е. [ ]).
- В маппинге для поля установлено значение "index": false.
- Длина значения поля ключевого слова превышает настройку ignore_above в маппинге.
- В маппинге было определено ignore_malformed, так как значение поля было искажено.
Как реализовать запрос exists
Запрос exists имеет один обязательный параметр - параметр field. Параметр field, имеющий строковый тип, представляет поле, по которому вы хотите выполнить поиск в индексе, возвращая документы, имеющие проиндексированное значение для этого поля.
В следующем запросе запрос exists будет искать в индексе "my_index" документы, имеющие индексированное значение для поля "my_field", и эти документы будут возвращены запросом exists.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | GET my_index/_search { "query": { "bool": { "filter": [ { "exists": { "field": "my_field" } } ] } } } |
Поле считается несуществующим, если его JSON-значение равно null или [ ]. Следующие значения указывают на то, что поле существует:
- Пустые строки, например "".
- Массивы, включающие null и другое значение, например [null, "foo"].
- В маппинге полей определяется пользовательское значение null.
Примечания
Поскольку булевый запрос используется для объединения нескольких запросов, запрос exists можно использовать внутри булевого запроса. Вы можете использовать булевский запрос must_not вместе с запросом exists, чтобы найти документы, в которых отсутствует индексированное значение для поля.
В следующем запросе поиск вернет документы из индекса "my_index", в которых отсутствует индексированное значение для поля "my_field".
1 2 3 4 5 6 7 8 9 10 11 12 | GET my_index/_search { "query": { "bool": { "must_not": { "exists": { "field": "my_field" } } } } } |
Запрос KQL Exists
Язык запросов Kibana (KQL) предоставляет простой синтаксис для поиска и фильтрации данных OpenSearch с помощью свободного текстового поиска или поиска по полям. KQL используется исключительно для фильтрации данных; он не играет никакой роли в их сортировке или агрегировании. Существует запрос KQL exists, эквивалентный запросу DSL exists, который работает аналогичным образом.
Запрос KQL exists сопоставляет документы, содержащие любое значение поля. В приведенном ниже примере будут найдены документы, содержащие любое значение поля user.
1 | user:* |
OpenSearch определяет существование, и оно включает все значения, в том числе и пустой текст. Как показано в примере, запрос KQL exists можно использовать, просто поместив имя поля, за которым следует :*, что означает; искать документы, в которых указанное поле существует в любой форме.
Чтобы найти документы, в которых отсутствует индексированное значение для поля, укажите "not" перед именем поля. В приведенном ниже примере будут найдены документы, в которых отсутствует значение для поля user.
1 | not user:* |
Заключение
- Запрос Exists - это DSL-запрос, который имеет тип "leaf query clauses" и является запросом на уровне термина.
- Запрос exists используется для возврата документов, которые имеют индексированное значение для определенного поля, поскольку некоторые поля в документах могут не иметь индексированного значения.
- Запрос Exists можно легко реализовать, установив один обязательный параметр, параметр field, в поле, которое вы хотите искать в индексе, чтобы вернуть документы, которые имеют проиндексированное значение для этого поля.
- Запрос exists можно использовать внутри булевого запроса.
- Используя булевский запрос must_not вместе с запросом exists, вы можете найти документы, в которых отсутствует индексированное значение поля.
- Существует запрос KQL exists, эквивалентный запросу DSL exists, который работает аналогичным образом и ищет документы, содержащие любое значение для поля.