Стратегия индексирования иерархических структур в ElasticSearch

#elasticsearch

Вопрос:

Допустим, у меня есть иерархические типы, такие как в примере ниже:

 base_type
    child_type1
        child_type3
    child_type2
 

child_type1 и child_type2 наследовать свойства метаданных от base_type . child_type3 обладает всеми свойствами, унаследованными от обоих child_type1 и base_type .

Чтобы добавить к примеру, вот несколько объектов со своими свойствами:

 base_type_object: {
    base_type_property: "bto_prop_value_1"
},
child_type1_object: {
    base_type_property: "ct1o_prop_value_1",
    child_type1_property: "ct1o_prop_value_2"
},
child_type2_object: {
    base_type_property: "ct2o_prop_value_1",
    child_type2_property: "ct2o_prop_value_2"
},
child_type3_object: {
    base_type_property: "ct3o_prop_value_1",
    child_type1_property: "ct3o_prop_value_2",
    child_type3_property: "ct3o_prop_value_3"
}
 

Когда я запрашиваю base_type_object , я ожидаю, что также буду искать base_type_property значения в каждом из дочерних типов. Аналогично, если я запрошу child_type1_property , я ожидаю, что буду искать по всем типам, которые имеют такое свойство, то есть объекты типа child_type1 и child_type3 .

Я вижу, что типы отображения были удалены. Мне интересно, гарантирует ли этот вариант использования индексацию по отдельным индексам.

Моя текущая линия мышления, используя приведенный выше пример, заключалась бы в создании 4 индексов: base_type_index , child_type1_index , child_type2_index и child_type3_index . Каждый индекс будет иметь только отображения своих собственных свойств, поэтому base_type_index будет иметь только base_type_property , child_type1_index будет иметь child_type1_property и т. Д. Индексирование child_type1_object создаст запись в обоих base_type_index child_type1_index индексах и. Это кажется удобным, потому что, насколько я вижу, можно выполнять поиск по нескольким индексам с помощью GET /my-index-000001,my-index-000002/_search . Поэтому теоретически мне просто нужно было бы перечислить иерархию моих типов в GET запросе: GET /base_type_index,child_type1_index/_search .

Чтобы было проще понять, вот как он будет проиндексирован:

базовый тип_индекс

 base_type_object: {
    base_type_property: "bto_prop_value_1"
},
child_type1_object: {
    base_type_property: "ct1o_prop_value_1"
},
child_type2_object: {
    base_type_property: "ct2o_prop_value_1",
},
child_type3_object: {
    base_type_property: "ct3o_prop_value_1",
}
 

child_type1_index

 child_type1_object: {
    child_type1_property: "ct1o_prop_value_2"
},
child_type3_object: {
    child_type1_property: "ct3o_prop_value_2",
}
 

Я думаю, что значения для child_type2_index и child_type3_index очевидны, поэтому я не буду перечислять их, чтобы сохранить длину записи на более разумном уровне.

Имеет ли это смысл и есть ли лучший способ индексирования для моего варианта использования?

Комментарии:

1. Если вы всегда собираетесь запрашивать все вместе, в чем преимущество размещения их в отдельных индексах по сравнению с размещением всего в одном базовом индексе (при условии отсутствия перекрытия свойств в дочерних объектах)?

2. Действительно, это хорошая причина для создания отдельных индексов, иначе эти перекрывающиеся свойства должны были бы иметь одно и то же определение (это было верно, даже если у вас может быть несколько типов отображения для каждого индекса). Я чувствую, что рискованно «распределять» объект по нескольким индексам. Как насчет повторения всех сопоставлений под каждым индексом? Таким образом, сопоставление «child_type1» будет иметь все свойства из child_type1, плюс свойства из базового типа и т. Д. Это однообразно, но вы могли бы автоматизировать. Другим вариантом может быть использование одного индекса и размещение подтипов во вложенных объектах.

3. При повторных сопоставлениях для каждого индекса, например, если я запрашиваю свойство базового типа, мне все равно придется указывать все индексы дочерних типов этого базового типа при поиске объектов, а затем агрегировать эти данные. Просто не люблю увольнений. Но вы, вероятно, правы, это действительно звучит как более интуитивный способ справиться со всем. Вложенные объекты — я добавил это в свой второй пост на форуме Elastic. discuss.elastic.co/t/best-way-to-index-hierarchical-types/… — вложенные типы-это то, как я реализовал это сначала, но я беспокоюсь, что взломал свой путь к устаревшим типам отображения.

4. Мне нравится, как вы использовали вложенный тип — таким образом, вы знаете, что нет перекрытия. В ES это выглядит как объект внутри объекта базового типа, но для Lucene это просто все поля. Вложенные объекты на самом деле не дают вам ничего сверх этого, так как у вас есть только 1 экземпляр на базовый экземпляр. Типы отображения были разными, потому что все поля сосуществовали в корне (из того, что я все равно понимаю — на самом деле я с ними не работал).

5. @NicolasGaller Да, мне тоже так кажется (несколько прямых потомков root), но тогда у моего предыдущего решения есть дубликат родителя (имя индекса первое сопоставление), который мне не слишком нравится, и это приводит к одному индексу, в котором я не так уверен. Я уже начал повторную реализацию так, как вы предложили, с повторяющимися сопоставлениями для каждого унаследованного типа, потому что, во всяком случае, будет легче понять и реализовать запросы для тех, кто придет после меня. Кажется, это самый интуитивный способ. Спасибо за ваш вклад, мне действительно нужен был толчок в любом направлении. Посмотрим, что из этого выйдет.