Parent-Child или plain документ

Добрый день.

Помогите определиться с оптимальной структурой для хранения документов.
Структура следующая Set<Company>->Set<Branch>->Set<Customer>. Компании имеют филиалы, в которых есть сотрудники. Основная задача это быстро искать, фильтровать, аггрегировать по полям customer и branch.

Есть 3 варианта.

  1. Хранить Company, Branch, Customer каждый в своем типе индекса и связать их через отношение parent-child.
  2. Хранить данные отдельно в каждом плоском документе Company+Branch+Customer
  3. Хранить в каждом документе дерево Company+Nested[Branch+Nested[Customer]]

Для всех вариантов elastic предлагает функционал для поиска, фильтрации и аггрегирования (не буду перечислять). Более того, как сказано в документации, nested поля это те же отдельные самостоятельные документы, которые elastic связывает через маппинг.

Только для parent-child есть некоторые ограничения, например:

Parent and child documents must be indexed on the same shard. The parent ID is used as the routing value for the child, to ensure that the child is indexed on the same shard as the parent. This means that the same parent value needs to be provided when getting, deleting, or updating a child document.

значит ли это, что я должен следить за тем, чтобы parent-child документы были проиндексированы на едином шарде?

При условии, что основная задача это быстро искать, фильтровать и аггрегировать по полям customer и branch, какой из способов хранения документов может быть оптимальным? Может быть какой-то из способов занимает больше места на диске или использует больше памяти, ведь для аггрегирования необходимо загрузить документы в память и тогда 2 вариант здесь более предпочтителен.

1 Like

Для детей и родителей elasticsearch следит за всем сам. Для внуков и правнуков и т.д. это достигается использованием параметра routing. К примеру,

PUT my_index/company/acme_corp - тут ничего делать не надо
PUT my_index/branch/acme_russia?parent=acme_corp - достаточно указать родителя, и эта запись попадет в туже шарду
PUT my_index/customer/vasya_pupkin?parent=acme_russia&routing=acme_corp - c этого уровня надо указывать и родителя в parent и прорадителя в routing

Надо смотреть на конкретные примеры поисков, объем данных на каждом уровне и как часто ити данные меняются для branch и company.

1 Like

Игорь, спасибо большое за ответ.

Еще раз перечитал раздел Modeling Your Data и нашел ответ на вопрос:

Parent-child joins can be a useful technique for managing relationships when index-time performance is more important than search-time performance, but it comes at a significant cost. Parent-child queries can be 5 to 10 times slower than the equivalent nested query!

1 Like

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.