← Назад к вопросам

Что такое Nested поля в Elastic Search?

2.0 Middle🔥 61 комментариев
#Базы данных#Микросервисы и архитектура

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI5 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Nested поля в Elasticsearch

Nested поля — это специальный тип данных в Elasticsearch, предназначенный для корректной индексации и поиска по массивам объектов, где объекты внутри массива должны рассматриваться как независимые документы. Это ключевое отличие от стандартного поведения object типа в массивах, где происходит "сглаживание" (flattening) полей, ведущее к потере связей между атрибутами внутри одного объекта массива.

Проблема, которую решает nested тип

Без использования nested, массив объектов индексируется в "сплющенном" виде. Это приводит к некорректным результатам при выполнении запросов с условиями на разные поля внутри одного элемента массива.

Рассмотрим пример документа с заказами:

{
  "order_id": 1,
  "items": [
    { "product": "Ноутбук", "price": 1000 },
    { "product": "Мышка", "price": 50 }
  ]
}

При маппинге items как обычного object, внутри Lucene (движка Elasticsearch) это будет преобразовано приблизительно так:

order_id: 1
items.product: ["Ноутбук", "Мышка"]
items.price: [1000, 50]

Проблема: Запрос "найти заказы, где есть товар 'Ноутбук' ценой 50 рублей" неожиданно вернет наш документ! Потому что Elasticsearch видит: в массиве items.product есть "Ноутбук", а в массиве items.price есть 50. Связь между конкретным продуктом и его ценой теряется.

Решение: Nested Mapping и Query

Для корректной работы необходимо:

  1. Объявить поле как nested в маппинге.
  2. Использовать специальные nested запросы и агрегации для работы с таким полем.

1. Создание маппинга с nested полем

PUT /orders
{
  "mappings": {
    "properties": {
      "order_id": { "type": "integer" },
      "items": {
        "type": "nested", // Ключевое объявление
        "properties": {
          "product": { "type": "keyword" },
          "price": { "type": "integer" }
        }
      }
    }
  }
}

Теперь каждый объект в массиве items индексируется как скрытый отдельный документ внутри основного документа, сохраняя связи своих полей.

2. Поиск по nested полям с помощью nested запроса

GET /orders/_search
{
  "query": {
    "nested": {
      "path": "items", // Указываем путь к nested полю
      "query": {
        "bool": {
          "must": [
            { "term": { "items.product": "Ноутбук" } },
            { "range": { "items.price": { "gte": 500 } } }
          ]
        }
      }
    }
  }
}

Этот запрос корректно найдет заказы, где существует ОДИН И ТОТ ЖЕ элемент массива items, у которого product равен "Ноутбук" И price больше или равен 500.

3. Агрегации по nested полям

Для корректного подсчета статистики по элементам вложенного массива также нужна специальная обертка:

GET /orders/_search
{
  "aggs": {
    "nested_items": {
      "nested": { "path": "items" },
      "aggs": {
        "avg_price": { "avg": { "field": "items.price" } }
      }
    }
  }
}

Ключевые особенности и важные замечания

  • Производительность: Nested запросы работают медленнее обычных, так как Elasticsearch должен обращаться к отдельным поддокументам. Слишком большое количество nested объектов может сказаться на производительности.
  • Ограничения: Изменение одного элемента в nested-массиве требует полной переиндексации всего родительского документа.
  • inner_hits: Полезный инструмент для отображения в результатах поиска именно тех вложенных объектов, которые удовлетворили условиям nested запроса.
    "nested": {
      "path": "items",
      "query": { ... },
      "inner_hits": {} // Добавит раздел с найденными совпадениями внутри массива
    }
    
  • Альтернативы: В версиях ES 7.x+ появился тип flattened для неструктурированных объектов, а для частых обновлений рассматривается join (parent-child) тип отношений. Однако nested остается оптимальным выбором для статических или редко изменяемых массивов объектов с необходимостью сложного поиска по их внутренним полям.

Вывод

Nested поля — это мощный и необходимый механизм Elasticsearch для работы со сложными связными данными внутри массивов. Они обеспечивают целостность запросов, но требуют внимательного подхода к проектированию маппингов и написанию запросов, а также осознания их влияния на производительность системы. Использование nested структур оправдано, когда критически важна корректность поиска по атрибутам, принадлежащим одному элементу массива.