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

Монгольские последствия обновления и замены

Я прочитал этот связанный вопрос, но ниже приведено другое. Драйвер mongodb С# имеет метод ReplaceOne (& amyn; aync-аналог) в классе коллекции документов, который может использоваться для замены всего содержимого документа, который соответствует аргументу фильтра. Альтернативой является использование методов UpdateOne или UpdateMany (или асинхронных копий), для чего требуется создание UpdateDefinition<TDocument>.

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

Первым фактором, о котором я могу думать, является полезная нагрузка, отправленная на сервер базы данных. Хотя я не читал ни одного источника драйверов mongodb С# и не мог найти никаких документов для проверки этого, кажется, что ReplaceOne может отправить больше байтов с операцией обновления, особенно для больших документов. Методы Update... кажутся, что они могут уйти с меньшей полезной нагрузкой, отправив только метаданные обновления для фрагментов документа, требующих модификации (в дополнение к критериям фильтра, которые оба метода должны отправить). Может ли кто-нибудь проверить, является ли это точным предположением?

Еще один фактор, вызванный коллегой, заключается в том, что выбор метода (обновление или замена) также может повлиять на индексацию документа. Предполагается, что использование ReplaceOne может привести к тому, что база данных будет восстанавливать все индексы для обновляемого документа, тогда как методы Update... имеют достаточную информацию метаданных изменения, чтобы избежать перестроения индексов в полях, которые не являются частью метаданных в определении обновления. Может ли кто-нибудь проверить, выполняет ли mongodb внутренне обработку индекса документа по-разному в зависимости от того, изменяется ли документ с помощью замены или обновления?

Третий фактор появился для нас несколько раз, в отношении методов AddToSet и PullFilter в классе Update<TDefinition>. Похоже, что методы Update... не позволят вам изменять набор в документе (например, json-массив) путем добавления к нему элементов и одновременного удаления элементов из него; эти операции должны отправляться индивидуально, используя 2 отдельных вызова метода Update... вместе с отдельными экземплярами Update<TDefinition> (хотя и с теми же аргументами фильтра). Метод ReplaceOne, в данном случае, кажется единственным способом сделать такое изменение документа в одной "транзакции", по крайней мере, при использовании драйвера С#. В настоящее время мы используем Update... над ReplaceOne, потому что мы не уверены, повлияет ли альтернатива на индексацию, как упомянуто выше.

Кроме этих, какие дополнительные последствия могут привести к выбору из семейства методов ReplaceOne в семействе Update... или наоборот? Опять же, это предполагает, что у вас достаточно входных данных (т.е. Всех данных документа) для достижения одного и того же результата при любом подходе, не обращайте внимания на мутирующее состояние напрямую (через замену) и не против создания определения mongo (через обновление).

4b9b3361

Ответ 1

Поскольку данные mongo неструктурированы, основное преимущество replaceOne vs Update заключается в том, что гарантировано, что все ваши поля будут удалены и заменены новым документом, что упростит запрос с вашей стороны

1) Правда, но наименьшая из ваших проблем, критерии поиска будут одинаковыми в обоих, но replaceOne потребует, чтобы весь документ был передан в запросе, по-прежнему стоит, когда у вас есть полный новый Doc, и хотите, чтобы конечно, это закончится таким образом

2) reindex on replace → yes, replaceOne заменяет всю документацию вместо обновления существующей, если вы обновляете элемент, находящийся в индексе, индекс должен будет перенастроить на изменение, но с заменой он будет всегда нужно перенастраиваться. индекс _id не влияет на обе операции (я думаю)

3) Если у вас уже есть значение, которым вы хотите быть, вам не нужно будет заменять полный документ, чтобы изменить одно поле, сделав его индексированным по всем полям, для этого вы должны использовать операцию $set, который вы могли бы рассматривать как ReplaceOne для одного поля, а не всего документа

https://docs.mongodb.com/manual/reference/method/db.collection.replaceOne/index.html https://docs.mongodb.com/manual/reference/operator/update/set/

Ответ 2

Если он включен в службу REST, метод replaceOne будет хорошо сочетаться с операцией PUT, где вы отправите целый объект в тело запроса вместе с идентификатором объекта, и это может быть полностью сохранено в базе данных, Отличительной характеристикой операции PUT является то, что она идемпотентна (вы можете запускать ее несколько раз). replaceOne принимает параметр upsert, который по умолчанию имеет значение false, но если для этого параметра было установлено значение true (а критерии поиска - в поле с уникальным индексированием), это сделало бы операцию повторяемой независимо от того, был ли документ независимо удален.

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