OpenSearch Вложенность: Вложенные поля или Объектные поля

OpenSearch logo OpenSearch

При определении сопоставлений OpenSearch будет конфигурировать поля, содержащие массив объектов, как тип " object".  Во многих случаях это нормально, но иногда сопоставления необходимо корректировать. Ниже мы рассмотрим различные сценарии и то, как выбрать правильное отображение для каждого случая.

Поля объектов

Одно из преимуществ использования структур на основе документов заключается в том, что их свойства можно группировать в иерархической форме. Это то, что мы называем объектами.

Объекты можно встраивать внутрь объектов и проникать в них настолько глубоко, насколько это необходимо.

Неважно, насколько глубока связь "объект в объекте", потому что OpenSearch внутренне сгладит ее (см. пояснения ниже).

В качестве значений свойств можно создавать массивы объектов.

В этой ситуации тип поля имеет значение, и иногда нам придется перейти от стандартного типа объекта к вложенному типу.

Тип вложенного поля

Что такое тип вложенного поля в OpenSearch?

Вложенный - это особый тип объекта, который индексируется как отдельный документ, и ссылка на каждый из этих внутренних документов хранится вместе с содержащим документом, так что мы можем запрашивать данные соответствующим образом.

Проблема с использованием объектных полей

Чтобы продемонстрировать использование объектных полей по сравнению с вложенными типами полей, мы сначала проиндексируем несколько документов. Примеры можно выполнить в OpenSearch Dashboards.

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

Давайте сосредоточимся на полях "authors" и "tags". Оба поля заданы как поля типа "объект". Это означает, что OpenSearch сгладит свойства. Документ 1 будет выглядеть следующим образом:

Как видите, поле "tags" выглядит как обычный строковый массив, но поле "authors" выглядит иначе - оно было разбито на множество полей массива.

Проблема в том, что OpenSearch не хранит свойства каждого объекта "authors" отдельно от свойств всех других объектов "authors".

Чтобы проиллюстрировать проблему с этим отображением, давайте рассмотрим два следующих запроса.

Запрос 1: Поиск книг с авторами из Чили или авторами, которым 30 лет или меньше.

Обе книги отвечают этим условиям.

Чтобы найти книги, соответствующие этим критериям, мы выполним следующий запрос:

Обе книги возвращены, что правильно, потому что Густаво Ллермали родом из Чили, а Джону Доу меньше 30 лет.

Запрос 2: Книги, написанные авторами, которым 30 лет или меньше и которые родом из Чили.

Ни одна книга не соответствует критериям.

Этот запрос также вернет оба документа, что неверно. Мы знаем, что единственному автору из Чили 32 года, и поэтому он не соответствует всем необходимым критериям, но OpenSearch не сохранил эту связь между авторами и возрастом.

Как решить эту проблему

Чтобы точно выполнить второй запрос, нам нужно использовать другой тип поля, называемый вложенным.

Вложенный - это особый тип объекта, который индексируется как отдельный документ, а ссылка на каждый из этих внутренних документов хранится вместе с содержащим документом, поэтому мы можем запросить данные соответствующим образом.

Нам придется изменить тип отображения. Чтобы изменить существующие отображения, нам нужно переиндексировать наши данные.

Сначала создайте пустой индекс, чтобы функция динамических сопоставлений OpenSearch не генерировала автоматически сопоставления для нашего поля authors:

OpenSearch создаст все остальные сопоставления на основе проиндексированных документов.

Теперь воспользуйтесь API reindex, чтобы переместить документы из старого индекса в новый:

Выполните эту операцию, чтобы убедиться, что документы переданы правильно:

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

Если мы снова попытаемся ответить на вопросы с помощью вложенных запросов, это будет выглядеть следующим образом:

Запрос 1: Ищем книги с авторами из Чили или авторами, которым 30 лет или меньше.

Обе книги по-прежнему появляются в результатах, что очень хорошо.

Запрос 2: Книги, написанные авторами в возрасте 30 лет или моложе и родом из Чили.

Ни одна книга не возвращается, что является ожидаемым результатом.

Почему это важно

Использование типа вложенного поля для каждого поля массива объекта "на случай, если оно понадобится позже" звучит заманчиво, но его следует использовать исключительно по мере необходимости. Под капотом Lucene создает новый документ для каждого объекта в массиве, и это может снизить производительность или даже привести к взрыву отображения.

Чтобы избежать низкой производительности, количество вложенных полей в одном индексе ограничено 50, а количество вложенных объектов в одном документе - 10000.

Обе настройки можно изменить, но делать это не рекомендуется:

  • index.mapping.nested_fields.limit
  • index.mapping.nested_objects.limit

Если вам нужно проиндексировать большое и непредсказуемое количество полей с ключевыми словами во внутренних объектах, вы можете использовать тип поля flattened, который отображает все содержимое объекта в одно поле и позволяет выполнять основные операции запроса.

Краткая информация

  • Поля, основанные на объектах или массивах объектов, по умолчанию создаются с типом object.
  • Объектный тип поля не поддерживает запрос связанных свойств внутри отдельных объектов.
  • Не используйте вложенный тип, если на один внешний объект будет приходиться только один внутренний объект.
  • В противном случае используйте поля вложенного типа (nested), если вам нужно запросить два или более полей в одном внутреннем объекте, в противном случае используйте объектный тип.
  • Слишком большое количество вложенных объектов может привести к снижению производительности или взрыву отображения.
  • Используйте сплющенный тип поля, чтобы сопоставить все поля ключевых слов внутреннего объекта одному полю.
Avatar for Gnostis
Gnostis
Добавить комментарий