Определение отношений между документами Elasticsearch с помощью объектов

elasticsearch logo Elasticsearch

Elasticsearch - это база данных документов, тип базы данных No-SQL, в которой данные хранятся в виде документов. Под "документами" в Elasticsearch подразумеваются документы JSON, а поскольку данные хранятся в формате JSON, эта база данных позволяет легко сохранять иерархию и структуру сложных данных. Дополнительным преимуществом является то, что хранение данных в формате JSON позволяет пользователям содержать свойства с различными типами данных в одном документе.

В отличие от баз данных SQL, Elasticsearch не выполняет операции объединения, которые могут замедлить время выполнения запроса, а стремится к получению результатов в режиме реального времени с миллисекундным временем отклика на запрос.

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

Иерархические объекты (объекты, содержащиеся в других объектах) создаются с помощью JSON. Elasticsearch демонстрирует уникальный тип данных, называемый объектным типом, который используется для представления иерархии объектов.

Использование типа поля объекта

Тип поля object позволяет пользователям использовать объект (с собственными полями и значениями) в качестве значения поля в документе.

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

Тип объекта - это самый простой способ представления группы интересов и связанных с ней событий. Это позволяет пользователям задавать значения полей в виде одного объекта JSON или в виде нескольких объектов JSON.

Как использовать тип поля object

Документы JSON имеют иерархическую структуру и могут содержать внутренние объекты, которые сами могут содержать другие внутренние объекты, как в примере ниже:

В этом примере индекс books содержит документы, каждый документ представляет собой книгу, а документы представлены в виде JSON-объектов, которые содержат те же свойства, что и книги. К ним относятся название и автор, где автор - это внутренний объект, содержащийся во внешнем объекте документа и имеющий два свойства, возраст и имя. Название - это внутренний объект, содержащийся в объекте author, который имеет два свойства, first и last, представляющие имя и фамилию автора книги.

Elasticsearch понимает поля и значения каждого объекта без знания его структуры.

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

Явное отображение документа будет выглядеть следующим образом:

Как показано выше, поле author представляет собой внутреннее объектное поле, а поле author.name - внутреннее объектное поле внутри этого поля. Поскольку объект является значением по умолчанию, нет необходимости явно присваивать объекту тип поля. См. ниже:

Пока корневой объект и внутренний объект имеют отношения "один к одному", сопоставление внутренних объектов, о котором говорилось выше, будет работать. Когда у книги только один "автор", это не проблема, однако если у книги, в данном случае "Machine Learning", два автора, а мы добавим еще одну книгу, "Artificial Intelligence", с одним автором, как показано ниже, это может вызвать проблемы:

Когда пользователи ищут книгу, написанную "Джоном Нейли", используя этот запрос:

они думают, что получат документ о книге "Искусственный интеллект". Однако когда пользователи действительно выполнят этот запрос, им будут возвращены оба документа. Поскольку Elasticsearch внутренне сплющивает внутренние объекты в один объект, запись о книге "Машинное обучение" будет выглядеть следующим образом:

Это объясняет, почему он возвращается в качестве результата. Поскольку Elasticsearch построен на плоском фундаменте, документы внутри представлены уплощенными полями.

Поле объекта принимает следующие параметры:

  • Dynamic: этот параметр определяет, нужно ли динамически добавлять дополнительные свойства к существующему объекту. Этот параметр может быть установлен в значения runtime, strict, true (значение по умолчанию) и false.
  • Enabled: этот параметр определяет, должно ли JSON-значение поля объекта индексироваться и разбираться (по умолчанию true) или полностью игнорироваться (false).
  • Subobjects: этот параметр определяет способность объекта содержать подобъекты (по умолчанию true) или нет (false). Если нет, то вложенные поля с точками в именах будут обрабатываться как листья, кроме того, имена полей будут расширены до соответствующей структуры объекта.
  • Properties: этот параметр представляет собой поля внутри объекта, которые могут быть любого типа данных, даже объектного. Новые свойства могут быть добавлены к существующему объекту.

Тип поля объекта - преимущества и недостатки

Преимущества

  • Они просты в использовании. В большинстве случаев пользователям не нужно делать ничего дополнительного для индексирования объектов, поскольку Elasticsearch автоматически обнаруживает их по умолчанию.
  • На объектах пользователи могут выполнять запросы и агрегации так же, как и на плоских документах. Это происходит потому, что на уровне Lucene они являются плоскими документами.
  • Никаких объединений не происходит.

Недостатки

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

Заключение

  • Использование типа поля объекта - это просто, быстро и эффективно. Однако он применим только в тех случаях, когда поддерживаются отношения "один к одному".
  • Elasticsearch не требует, чтобы тип данных поля был явно определен как объект в отображении. Когда он сталкивается с полями с иерархическими данными, он динамически устанавливает тип данных поля как объект.
  • Придав всему полю путь с точечной нотацией, например author.name, пользователи могут выполнять поиск в поле объекта.
  • Из-за того, что тип объекта индексируется, объекты отлично работают, когда пользователям нужно запросить только одно поле объекта за раз (обычно это отношения один-к-одному), но когда пользователям нужно запросить несколько полей (как это обычно бывает в отношениях один-ко-многим), они могут получить неожиданные результаты.
  • Использование типа поля объекта ограничивает пользователей, сглаживая внутренние объекты вместо того, чтобы хранить их в виде отдельных документов. При этом теряется связь между объектами, индексируемыми из массива, что является недостатком. Однако для решения этой проблемы можно использовать тип вложенного поля.
Avatar for Gnostis
Gnostis
Добавить комментарий