terms
Terms Query (Поиск по нескольким значениям)
Основное назначение
Запрос terms
позволяет искать документы, содержащие одно или несколько указанных значений в заданном поле. Документ возвращается в результатах, если значение его поля точно соответствует хотя бы одному термину из списка.
Базовый синтаксис
GET shakespeare/_search
{
"query": {
"terms": {
"line_id": [
"61809",
"61810"
]
}
}
}
Ключевые особенности
-
Лимит терминов:
По умолчанию максимальное количество терминов в запросе - 65,536. Настраивается через параметрindex.max_terms_count
. -
Производительность:
Для оптимизации производительности с длинными списками терминов рекомендуется:- Передавать термины в отсортированном порядке (по возрастанию UTF-8 byte values)
- Использовать механизм Terms Lookup для больших наборов терминов
-
Подсветка результатов:
Возможность подсветки результатов зависит от:- Типа highlighter’а
- Количества терминов в запросе
Параметры запроса
Параметр | Тип данных | Описание | По умолчанию |
---|---|---|---|
<field> |
String | Поле для поиска (точное соответствие хотя бы одному термину) | - |
boost |
Float | Вес поля в расчете релевантности (>1 - увеличивает, 0-1 - уменьшает) | 1.0 |
_name |
String | Имя запроса для тегирования | - |
value_type |
String | Тип значений для фильтрации (default или bitmap ) |
default |
Terms Lookup (Поиск терминов из другого документа)
Общие принципы
Механизм Terms Lookup позволяет:
- Извлекать значения полей из указанного документа
- Использовать эти значения как условия поиска
- Работать с большими наборами терминов
Требования:
- Поле
_source
должно быть включено (включено по умолчанию) - Для уменьшения сетевого трафика рекомендуется использовать индекс с:
- Одним первичным шардом
- Полными репликами на всех узлах данных
Пример использования
- Создаем индекс студентов:
PUT students
{
"mappings": {
"properties": {
"student_id": { "type": "keyword" }
}
}
}
- Добавляем данные студентов:
PUT students/_doc/1
{
"name": "Jane Doe",
"student_id" : "111"
}
PUT students/_doc/2
{
"name": "Mary Major",
"student_id" : "222"
}
PUT students/_doc/3
{
"name": "John Doe",
"student_id" : "333"
}
- Создаем индекс классов с информацией о зачисленных студентах:
PUT classes/_doc/101
{
"name": "CS101",
"enrolled" : ["111" , "222"]
}
- Поиск студентов, зачисленных на CS101:
GET students/_search
{
"query": {
"terms": {
"student_id": {
"index": "classes",
"id": "101",
"path": "enrolled"
}
}
}
}
- Результат содержит соответствующих студентов:
{
"took": 13,
"hits": {
"total": {
"value": 2,
"relation": "eq"
},
"hits": [
{
"_index": "students",
"_id": "1",
"_source": {
"name": "Jane Doe",
"student_id": "111"
}
},
{
"_index": "students",
"_id": "2",
"_source": {
"name": "Mary Major",
"student_id": "222"
}
}
]
}
}
Работа с вложенными полями
- Добавляем документ с вложенной структурой:
PUT classes/_doc/102
{
"name": "CS102",
"enrolled_students" : {
"id_list" : ["111" , "333"]
}
}
- Поиск с указанием пути к вложенному полю:
GET students/_search
{
"query": {
"terms": {
"student_id": {
"index": "classes",
"id": "102",
"path": "enrolled_students.id_list"
}
}
}
}
- Результат поиска:
{
"took": 18,
"hits": {
"total": {
"value": 2,
"relation": "eq"
},
"hits": [
{
"_index": "students",
"_id": "1",
"_source": {
"name": "Jane Doe",
"student_id": "111"
}
},
{
"_index": "students",
"_id": "3",
"_source": {
"name": "John Doe",
"student_id": "333"
}
}
]
}
}
Параметры Terms Lookup
Параметр | Тип данных | Описание | Обязательность |
---|---|---|---|
index |
String | Индекс, из которого извлекаются значения | Обязательно |
id |
String | ID документа-источника | Обязательно |
path |
String | Путь к полю (для вложенных полей - точечная нотация) | Обязательно |
routing |
String | Кастомное значение маршрутизации документа | Опционально* |
store |
Boolean | Использовать stored fields вместо _source |
Опционально |
*Обязателен, если при индексации использовалось кастомное routing
Важные замечания
- Для полей типа
text
используйтеmatch
вместоterms
- При работе с большими наборами терминов (>10,000) рассмотрите возможность использования Bitmap Filtering
- Убедитесь, что поле
_source
включено для документов-источников
Bitmap Filtering (Фильтрация с использованием битовых карт)
Введение
Начиная с версии 2.17, OpenSearch предлагает механизм bitmap filtering для эффективной фильтрации по большому количеству терминов (10,000+). Этот подход решает проблему высокой нагрузки на сеть и память при работе с обычными terms-запросами.
Основные концепции
-
Проблема:
Обычные terms-запросы становятся неэффективными при большом количестве терминов из-за:- Высокого сетевого трафика
- Чрезмерного потребления памяти
-
Решение:
Использование roaring bitmap для кодирования условий фильтрации:- Эффективное сжатие данных
- Быстрые битовые операции
- Оптимизированное использование памяти
Пример реализации
1. Подготовка индексов
Индекс продуктов:
PUT /products
{
"mappings": {
"properties": {
"product_id": { "type": "integer" }
}
}
}
Добавление продуктов:
PUT /products/_doc/1
{
"name": "Product 1",
"product_id" : 111
}
PUT /products/_doc/2
{
"name": "Product 2",
"product_id" : 222
}
PUT /products/_doc/3
{
"name": "Product 3",
"product_id" : 333
}
Индекс клиентов с bitmap-полем:
PUT /customers
{
"mappings": {
"properties": {
"customer_filter": {
"type": "binary",
"store": true
}
}
}
}
2. Генерация bitmap
Пример кода на Python с использованием PyRoaringBitMap:
from pyroaring import BitMap
import base64
bm = BitMap([111, 222, 333]) # ID продуктов клиента
encoded = base64.b64encode(BitMap.serialize(bm))
encoded_bm_str = encoded.decode('utf-8')
print(f"Encoded Bitmap: {encoded_bm_str}")
3. Индексация bitmap
POST customers/_doc/customer123
{
"customer_filter": "OjAAAAEAAAAAAAIAEAAAAG8A3gBNAQ=="
}
Использование bitmap в запросах
Вариант 1: Lookup из документа
POST /products/_search
{
"query": {
"terms": {
"product_id": {
"index": "customers",
"id": "customer123",
"path": "customer_filter",
"store": true
},
"value_type": "bitmap"
}
}
}
Вариант 2: Прямая передача bitmap
POST /products/_search
{
"query": {
"terms": {
"product_id": [
"OjAAAAEAAAAAAAIAEAAAAG8A3gBNAQ=="
],
"value_type": "bitmap"
}
}
}
Ключевые параметры
Параметр | Тип данных | Описание | Обязательность |
---|---|---|---|
value_type |
String | Должно быть bitmap для активации этого режима |
Обязательно |
store |
Boolean | true для поиска в stored field вместо _source |
Опционально |
index |
String | Индекс-источник bitmap (для lookup) | Для lookup |
id |
String | ID документа с bitmap | Для lookup |
path |
String | Поле с bitmap данными | Для lookup |
Преимущества подхода
-
Эффективность:
- Снижение сетевого трафика до 10 раз
- Уменьшение использования памяти на 50-90%
-
Гибкость:
- Поддержка динамического обновления фильтров
- Возможность комбинирования условий
-
Производительность:
- Быстрое выполнение даже для 100,000+ терминов
- Оптимизированные битовые операции на уровне ядра
Рекомендации
- Используйте для сложных фильтров с >10,000 значений
- Регулярно обновляйте bitmap при изменении данных
- Тестируйте производительность для вашего конкретного сценария
- Рассмотрите использование сжатых форматов bitmap для экономии места