2012-06-25 19 views
6

Tengo la colección domain con documentos que contienen información de dominio. Parte de eso son los registros whois históricos, que pueden ser cero o más y ocupan con mucho la mayoría del espacio para el documento.MongoDB: ¿Guardar un documento reescribe todo el documento?

Si cargué todo el documento, cambio algo pequeño (como actualizar un campo numérico) y uso el método save() mongo vaciar todo el documento en el disco o solo actualizar el BSON que ha cambiado? En definitiva, mi pregunta es, ¿debería molestarme en complicar mi código con update() para ahorrar en E/S o debería simplemente usar save()?

Esto no se debe exclusivamente a la pereza, el documento (después de que se lee en su totalidad) pasa por una serie de pasos para modificar/procesar el documento y si se han realizado cambios se guarda todo el documento. Pero si el costo de guardar el documento es alto, entonces tal vez tenga que pensarlo de otra manera ...

Respuesta

4

Puede actualizar un solo campo en un documento con $set. Esto modificará el campo en el disco. Sin embargo, if the document grows beyond the size before the update, the document may have to be relocated on disk.

Mientras tanto, here is what the documentation says about save versus update:

>// x is some JSON style object 
>db.mycollection.save(x); // updates if exists; inserts if new 
> 
>// equivalent to: 
>db.mycollection.update({ _id: x._id }, x, /*upsert*/ true); 

Referencias

+0

Eso es útil, pero realmente no responde mi pregunta. Si tengo un documento de 10mb BSON, lo leo cambiando una propiedad y guardándola ¿volverá a escribir los 10mb completos? Suponiendo que el documento no tiene que ser reubicado. –

+0

El detalle en * "está escrito en su totalidad" * depende del hecho de que MongoDB utiliza archivos mapeados en memoria. Si solo actualiza una sola propiedad, lo ideal es que solo esos bytes se vacíen en el disco. Sin embargo, si el BSON cambia lo suficiente, entonces * usted * podría terminar descargando todo al disco. –

+1

@GatesVP: pensé que toda la página está marcada como sucia y tiene que enjuagarse. –

2

Esto depende de la biblioteca de cliente que esté utilizando. Por ejemplo, Mongoid (ODM en ruby) es lo suficientemente inteligente como para enviar solo los campos que fueron cambiados (usando el comando $set). A veces es demasiado inteligente y no detecta los cambios que hice a hashes anidados. Pero nunca lo he visto enviar campos sin cambios.

Otras bibliotecas/controladores pueden comportarse de manera diferente.

0

Sé que esta pregunta es antigua, pero es muy útil saber cómo funciona para ayudarlo a diseñar la estructura de su base de datos. Aquí están los detalles sobre el motor de almacenamiento de MongoDB: https://docs.mongodb.com/v3.2/faq/storage/

El documento responde la pregunta. Básicamente, si actualiza un campo entero en MongoDB, marcará la página (normalmente 4k) en la memoria donde reside el número entero para que esté sucia y escribirá la página de memoria en el siguiente enjuague de disco. Por lo tanto, si el tamaño de su documento es muy grande, existe la posibilidad de que solo escriba parte del documento en el disco.

Sin embargo, hay muchos otros casos. Si está agregando más datos a su documento, hay posibilidades de que MongoDB necesite mover todo el documento a una nueva ubicación para que el documento crezca. En ese caso, todo el documento se escribirá en el disco.

Cuestiones relacionadas