Подтвердить что ты не робот

Эластичный поиск, можно ли обновлять вложенные объекты без обновления всего документа?

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

4b9b3361

Ответ 1

Вы можете использовать API обновления.

curl -XPOST localhost:9200/docs/posts/post/_update -d '{
    "script" : "ctx._source.nested_user = updated_nested_user",
    "params" : {
        "updated_nested_user" : {"field": "updated"}
    }
}'

Смотрите этот так ответ для полной информации.

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

curl -XPOST 'localhost:9200/docs/posts/post/_update' -d '{
    "script" : "ctx._source.tags.contains(tag) ? "ctx._source.nested_user = updated_nested_John" : ctx.op = "none"",
    "params" : {
        "tag": "updated_John_tag",
        "updated_nested_John" : {"field": "updated"}
    }
}'

ОБНОВЛЕНО

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

curl -XPOST 'localhost:9200/docs/posts/post/_update' -d '{
    "script" : "ctx._source.nested_user.contains(user) ? "ctx._source.nested_user = updated_nested_John" : ctx.op = "none"",
    "params" : {
        "user": "John",
        "updated_nested_John" : {"field": "updated"}
    }
}'

Как уже упоминалось, это может быть более медленной операцией, чем переиндексация полных сообщений.

Ответ 2

Печально elasticsearch не может обновить только часть документа без переиндексации всего документа. Итак, да, вам нужно будет переиндексировать весь документ, чтобы изменить вложенную часть.

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

Ответ 3

Ответа на этот вопрос @Scott Rice о том, как использовать частичное обновление в этом контексте, очень полезно, в то время как ответ by @ramseykhalaf более правилен в том смысле, что это невозможно без переиндексации. Если мы выполняем частичное обновление, мы все равно переиндексируем весь документ.

Однако зависит от понимания того, что такое "переиндексирование".

Если мы определим переиндексацию как "повторный ввод всего документа в ES", мы можем вызвать частичное обновление решения без переиндексации в этом смысле. Если мы определим переиндексацию как "перерасчет структур данных, позволяющих эффективно искать обновленный документ в индексе" (что является более правильным определением для моего понимания), то это всегда происходит.

Обратите внимание, что вся старая копия документа останется в индексе после частичного обновления, помечена как удаленная (до следующего полного переиндекса с нуля или "оптимизация" ).

Чтобы избежать этого, вместо вложенных объектов можно использовать дочерние и родительские отношения. Дети могут быть добавлены/удалены/обновлены, не касаясь родительского документа (однако у него есть его стоимость, конечно, - сохранение отношений между родительскими родителями и дочерними элементами в памяти и т.д.).

Ответ 4

Вы можете обновить вложенный файл вasticsearch, смотрите видео ниже для получения дополнительной информации: https://www.youtube.com/watch?v=A3aldCB6i0A