c# - per - Implicaciones de Mongodb de actualización versus reemplazo
mongodb net c# (2)
He leído esta pregunta relacionada , pero la siguiente es diferente. El controlador mongodb c # tiene un método ReplaceOne
(y una contraparte asíncrona) en la clase de colección de documentos, que se puede usar para reemplazar todo el contenido de un documento que se ajusta al argumento del filtro. La alternativa es usar los métodos UpdateOne
o UpdateMany
(o contrapartes asíncronas), que requieren la construcción de un UpdateDefinition<TDocument>
.
Mi pregunta tiene que ver con las implicaciones de elegir uno de estos métodos sobre el otro (reemplazar vs actualizar), en los casos en que tenga suficientes datos de entrada para elegir, ya sea para lograr el mismo resultado. En otras palabras, si tengo todo el documento original y solo deseo actualizar una pequeña parte de su contenido.
El primer factor que se me ocurre es la carga útil enviada al servidor de la base de datos. Aunque no he leído ninguna fuente de controlador mongodb c # y no pude encontrar ningún documento para verificar esto, parece que ReplaceOne
podría tener que enviar más bytes con la operación de actualización, especialmente para documentos más grandes. Los métodos de Update...
parece que podrían salirse con una carga útil más pequeña al enviar solo metadatos de actualización para los segmentos del documento que requieren modificación (además de los criterios de filtro, que ambos métodos deben enviar). ¿Alguien puede verificar si esta es una suposición precisa?
Otro factor planteado por un colega es que la elección del método (actualización frente a reemplazo) también podría afectar la indexación de documentos. El supuesto aquí es que el uso de ReplaceOne
puede hacer que la base de datos reconstruya todos los índices para el documento que se está actualizando, mientras que los métodos de Update...
tienen suficiente información de metadatos para evitar la reconstrucción de índices en campos que no forman parte de los metadatos en la definición de actualización. ¿Alguien puede verificar si mongodb maneja internamente la creación de índices de documentos de manera diferente dependiendo de si un documento se modifica con reemplazar en lugar de actualizar?
Un tercer factor surgió para nosotros un par de veces, con respecto a los métodos AddToSet
y PullFilter
en la clase Update<TDefinition>
. Parece que los métodos de Update...
no le permitirán modificar un conjunto en un documento (como una matriz json) al agregarle elementos y eliminarlos al mismo tiempo; estas operaciones deben enviarse individualmente, utilizando 2 llamadas separadas al método Update...
junto con las instancias separadas de Update<TDefinition>
(aunque con los mismos argumentos de filtro). El método ReplaceOne
, en este caso, parece ser la única forma de realizar este tipo de cambio de documento en una sola "transacción", al menos cuando se usa el controlador C #. Actualmente estamos usando Update...
sobre ReplaceOne
por ahora porque no estamos seguros de que la alternativa afecte negativamente la indexación como se mencionó anteriormente.
Aparte de estos, ¿cuáles son las implicaciones adicionales que podrían llevarlo a elegir de la familia de métodos ReplaceOne
sobre la familia Update...
o viceversa? Nuevamente, esto es asumiendo que tiene suficientes datos de entrada (es decir, todos los datos del documento) para lograr el mismo resultado con cualquiera de los dos enfoques, no importa el estado de mutación directamente (a través de reemplazar), y no le importa crear definiciones de Mongo (a través de la actualización) .
Como los datos de Mongo no están estructurados, la principal ventaja de la actualización de reemplazo contra una es que está garantizada que se eliminarán todos sus campos y se los reemplazará por el nuevo documento, lo que simplifica la consulta.
1) Cierto, pero el menor de sus problemas, los criterios de búsqueda serán los mismos en ambos, pero replaceOne requerirá que se pase todo el documento en la consulta, aún vale la pena cuando tiene el nuevo Doc completo y desea estar seguro de que terminar de esa manera
2) reindexar al reemplazar -> sí, reemplazar. Reemplazar todo el documento en lugar de actualizar uno existente, si actualiza en el elemento que está en el índice, el índice deberá reajustarse al cambio, pero con el reemplazo siempre tendrá que reajustar. El índice _id no se ve afectado por ambas operaciones (creo)
3) Si ya tiene el valor que desea ser, no tendría que reemplazar el documento completo para cambiar un solo campo, por lo que todos los campos lo indexarán, debería usar la operación $ set para eso, lo que podría piense como un ReplaceOne para un solo campo en lugar de todo el documento
https://docs.mongodb.com/manual/reference/method/db.collection.replaceOne/index.html https://docs.mongodb.com/manual/reference/operator/update/set/
Si se incorpora en un servicio REST, el método replaceOne se alinearía bien con una operación PUT, donde enviaría un objeto completo en su cuerpo de solicitud junto con un identificador de objeto, y esto podría persistir en la base de datos en su totalidad. La característica distintiva de una operación PUT es que es idempotente (puede ejecutarla repetidamente). replaceOne
toma una opción de upsert
que su valor predeterminado es falso, pero si se estableciera en verdadero (y los criterios de búsqueda se encontraban en un campo indexado únicamente) haría que la operación fuera repetible, independientemente de si el documento se eliminó de forma independiente.
La operación de actualización es más parecida a una operación POST, ya que solo actualiza parte de un documento en lugar de reemplazarlo por completo. También tiene una opción de upsert
, pero si otro documento eliminó el documento, el documento resultante podría tener un formato incorrecto y la actualización podría fallar.