Query DSL - язык запросов OpenSearch

OpenSearch предоставляет мощный язык запросов (Query Domain-Specific Language), основанный на JSON-синтаксисе. Этот язык позволяет выполнять гибкий и точный поиск по данным.

Введение в 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” как два отдельных термина.

Решение:

  1. Использовать keyword тип поля для точного совпадения
  2. Настроить кастомный анализатор

Ресурсоемкие запросы

Типы затратных запросов:

  • Нечеткий поиск (fuzzy)
  • Поиск по префиксу (prefix)
  • Диапазонные запросы по текстовым полям
  • Регулярные выражения (regexp)
  • Wildcard-запросы
  • Сложные query_string запросы

Защита от ресурсоемких запросов:

PUT _cluster/settings
{
  "persistent": {
    "search.allow_expensive_queries": false
  }
}

Мониторинг: Для отслеживания медленных запросов используйте shard slow logs.

Рекомендации по использованию

  1. Для точного соответствия используйте keyword тип полей
  2. Избегайте специальных символов в текстовых полях
  3. Мониторьте ресурсоемкие запросы
  4. Для сложной логики комбинируйте запросы через bool
  5. Используйте explain для анализа работы запросов