Лучше хранить вложенные данные или использовать плоскую структуру с уникальными именами в JSON? - PullRequest
1 голос
/ 30 октября 2019

Проще говоря:

{
    "diary":{
        "number":100,
        "year":2006
    },
    "case":{
        "number":12345,
        "year":2006
    }
}

или

{
    "diary_number":100,
    "diary_year":2006,
    "case_number":12345,
    "case_year":2006

}

лучше при использовании Elasticsearch?

В моем случае всего ключей всего несколько (10-15). Что лучше по производительности?

Вариант использования отображает данные из базы данных noSQL (в основном, DynamoDB). Также подает его в Elasticsearch.

Ответы [ 3 ]

0 голосов
/ 30 октября 2019

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

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

Вот выдержка из Управление отношениями внутри Elasticsearch , в которой перечислены некоторые недостатки, которые вы, возможно, захотите рассмотреть.

Elasticsearch все еще принципиально плоский, но он управляет вложенными отношениями внутри, чтобы создать видимость вложенной иерархии. Когда вы создаете вложенный документ, Elasticsearch фактически индексирует два отдельных документа (корневой объект и вложенный объект), а затем связывает их внутренне. Оба документа хранятся в одном и том же блоке Lucene на одном и том же шарде, поэтому производительность чтения все еще очень высока.

Такое расположение имеет некоторые недостатки. Наиболее очевидно, что вы можете получить доступ к этим вложенным документам только с помощью специального nested query. Другой большой недостаток возникает, когда вам необходимо обновить документ, либо корневой, либо любой из объектов.

Поскольку все документы хранятся в одном блоке Lucene, а Lucene никогда не разрешает произвольный доступ для записи в его сегменты,Обновление одного поля во вложенном документе приведет к переиндексации всего документа.

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

Наконец, невозможно «перекрестно ссылаться» между вложенными документами. Один вложенный документ не может "видеть" свойства другого вложенного документа. Например, вы не можете фильтровать по «A.name», но фасетировать по «B.age». Вы можете обойти это, используя include_in_root, который эффективно копирует вложенные документы в корень, но это возвращает вас к проблемам внутренних объектов.

0 голосов
/ 31 октября 2019

Вложенные данные довольно хороши. Если вы явно не объявите diary и case как вложенное поле, они будут проиндексированы как object поля. Таким образом ,asticsearch сам конвертирует их в

{
    "diary.number":100,
    "diary.year":2006,
    "case.number":12345,
    "case.year":2006

}

. Учтите также, что каждое значение поля вasticsearch может быть массивом . Тип данных nested нужен только в том случае, если в одном документе много дневников, и вам необходимо «поддерживать независимость каждого объекта в массиве».

0 голосов
/ 30 октября 2019

Ответ ясен - зависит. JSON славится своими вложенными структурами. Тем не менее, есть некоторые инструменты, которые могут работать только со структурами ключ-значение и плоскими JSON, и Я чувствую, что Elastic более интересен для плоских JSON, особенно если вы используете Logstash , см., Например, https://discuss.elastic.co/t/what-is-the-best-way-of-getting-mongodb-data-into-elasticsearch/40840/5

Я счастлив, что оказался неправ ..

...