Query DSL - язык запросов OpenSearch
Введение в Query DSL
OpenSearch предоставляет мощный язык запросов (Query Domain-Specific Language), основанный на JSON-синтаксисе. Этот язык позволяет выполнять гибкий и точный поиск по данным.
Базовый пример запроса:
GET testindex/_search
{
"query": {
"match_all": {}
}
Этот запрос возвращает все документы в указанном индексе.
Типы запросов
Запросы делятся на две основные категории:
1. Листовые запросы (Leaf queries)
Особенности:
- Выполняют поиск по конкретным полям
- Могут использоваться самостоятельно
- Не содержат других запросов
Основные типы:
1.1 Полнотекстовые запросы:
- Анализируют текст запроса
- Применяют тот же анализатор, что и при индексации
- Примеры:
match
,match_phrase
,multi_match
1.2 Термино-уровневые запросы:
- Ищут точные значения без анализа текста
- Не учитывают релевантность
- Примеры:
term
,terms
,range
,exists
1.3 Геопространственные запросы:
- Работают с географическими данными
- Примеры:
geo_distance
,geo_bounding_box
1.4 Запросы соединений:
- Для работы с вложенными документами
- Примеры:
nested
,has_child
,has_parent
1.5 Позиционные запросы (Span queries):
- Точный поиск с учетом позиции терминов
- Часто используются для юридических документов
1.6 Специализированные запросы:
more_like_this
- поиск похожих документовscript
- запросы с использованием скриптовpercolate
- обратный поиск
2. Составные запросы (Compound queries)
Особенности:
- Объединяют несколько запросов
- Модифицируют поведение дочерних запросов
- Управляют логикой выполнения
Основные типы:
bool
- булева комбинация запросовdis_max
- поиск по нескольким полямconstant_score
- задает фиксированную релевантностьfunction_score
- кастомные алгоритмы релевантности
Особенности обработки специальных символов
Проблема: Стандартный анализатор некорректно обрабатывает Unicode-символы (например, дефис), что может привести к:
- Неожиданным результатам поиска
- Проблемам контроля доступа
Пример проблемы:
{
"match": {
"user.id": "User-1"
}
}
Анализатор может интерпретировать “User-1” как два отдельных термина.
Решение:
- Использовать
keyword
тип поля для точного совпадения - Настроить кастомный анализатор
Ресурсоемкие запросы
Типы затратных запросов:
- Нечеткий поиск (
fuzzy
) - Поиск по префиксу (
prefix
) - Диапазонные запросы по текстовым полям
- Регулярные выражения (
regexp
) - Wildcard-запросы
- Сложные
query_string
запросы
Защита от ресурсоемких запросов:
PUT _cluster/settings
{
"persistent": {
"search.allow_expensive_queries": false
}
}
Мониторинг: Для отслеживания медленных запросов используйте shard slow logs.
Рекомендации по использованию
- Для точного соответствия используйте
keyword
тип полей - Избегайте специальных символов в текстовых полях
- Мониторьте ресурсоемкие запросы
- Для сложной логики комбинируйте запросы через
bool
- Используйте
explain
для анализа работы запросов