Сравнение термовых и полнотекстовых запросов

Термовые (term-level) и полнотекстовые (full-text) запросы используются для поиска по тексту, но имеют принципиальные отличия

Основные различия

Термовые (term-level) и полнотекстовые (full-text) запросы используются для поиска по тексту, но имеют принципиальные отличия:

Характеристика Термовые запросы Полнотекстовые запросы
Описание Определяют, какие документы соответствуют запросу Оценивают, насколько хорошо документы соответствуют запросу
Анализатор Поисковый терм не анализируется Используется тот же анализатор, что и при индексации поля
Релевантность Не сортируют результаты по релевантности Рассчитывают оценку релевантности и сортируют результаты
Использование Точные значения (числа, даты, теги) Текстовые поля с учетом морфологии и вариантов слов

OpenSearch использует алгоритм ранжирования BM25 для расчета оценок релевантности.

Когда использовать каждый тип запроса?

Пример 1: Поиск фразы

Рассмотрим поиск фразы “To be, or not to be” в произведениях Шекспира.

Термовый запрос:

GET shakespeare/_search
{
  "query": {
    "term": {
      "text_entry": "To be, or not to be"
    }
  }
}

Результат:

{
  "took": 3,
  "hits": {
    "total": {
      "value": 0,
      "relation": "eq"
    },
    "hits": []
  }
}

Запрос не нашел совпадений, так как ищет точную неизмененную фразу.

Полнотекстовый запрос:

GET shakespeare/_search
{
  "query": {
    "match": {
      "text_entry": "To be, or not to be"
    }
  }
}

Результат (сокращенный):

{
  "took": 19,
  "hits": {
    "total": {
      "value": 10000,
      "relation": "gte"
    },
    "hits": [
      {
        "_score": 17.419369,
        "_source": {
          "text_entry": "To be, or not to be: that is the question:"
        }
      },
      {
        "_score": 14.883024,
        "_source": {
          "text_entry": "Not like a corse; or if, not to be buried,"
        }
      }
    ]
  }
}

Полнотекстовый запрос нашел релевантные результаты, проанализировав фразу.

Пример 2: Поиск точного термина

Для поиска точного значения “HAMLET” в поле speaker эффективнее термовый запрос:

GET shakespeare/_search
{
  "query": {
    "term": {
      "speaker": "HAMLET"
    }
  }
}

Результат (сокращенный):

{
  "took": 5,
  "hits": {
    "total": {
      "value": 1582,
      "relation": "eq"
    },
    "hits": [
      {
        "_score": 4.2540946,
        "_source": {
          "speaker": "HAMLET",
          "text_entry": "[Aside] A little more than kin..."
        }
      },
      {
        "_score": 4.2540946,
        "_source": {
          "speaker": "HAMLET",
          "text_entry": "Not so, my lord..."
        }
      }
    ]
  }
}

Важно: Поиск по “Hamlet” не даст результатов, так как поле speaker является keyword и хранится в исходном регистре.

Рекомендации по выбору типа запроса

  1. Используйте термовые запросы для:

    • Точных значений (ID, коды, категории)
    • Полям типа keyword
    • Когда не нужна сортировка по релевантности
  2. Используйте полнотекстовые запросы для:

    • Текстового поиска с анализом
    • Когда важна оценка релевантности
    • Поиска по словоформам и синонимам
  3. Для полей text:
    Всегда используйте полнотекстовые запросы, так как их значения анализируются при индексации.

  4. Для полей keyword:
    Используйте термовые запросы для точного соответствия.