Overview
MongoDB proporciona a los clientes la capacidad de realizar operaciones de escritura en bloque. Las operaciones de guardar en bloque afectan a una única colección. MongoDB permite que las aplicaciones determinen el nivel aceptable de reconocimiento requerido para las operaciones de escritura masiva.
Novedad en la versión 3.2.
La db.collection.bulkWrite() El método proporciona la capacidad de realizar operaciones de inserción, actualización y eliminación masivas.
MongoDB también admite la inserción masiva a través del método db.collection.insertMany().
Operaciones ordenadas frente a desordenadas
Las operaciones de escritura masiva pueden ser ordenadas o desordenadas.
Con una lista ordenada de operaciones, MongoDB ejecuta las operaciones de forma serial. Si se produce un error durante el procesamiento de una de las operaciones de guardar, MongoDB devolverá la operación sin procesar el resto de las operaciones de guardar de la lista. Ver Bulk guardar Ordenada
Con una lista desordenada de operaciones, MongoDB puede ejecutar las operaciones en paralelo, pero este comportamiento no está garantizado. Si se produce un error durante el procesamiento de una de las operaciones de guardar, MongoDB seguirá procesando las operaciones de guardar restantes en la lista. Consulta el Ejemplo de escritura masiva desordenada.
La ejecución de una lista ordenada de operaciones en una colección fragmentada generalmente será más lenta que la ejecución de una lista desordenada, ya que con una lista ordenada, cada operación debe esperar a que la operación anterior termine.
De forma predeterminada, bulkWrite() realiza ordered operaciones. Para especificar unordered operaciones de escritura, configure ordered : false en el documento de opciones.
Consulta Ejecución de operaciones
Métodos bulkWrite()
bulkWrite() admite las siguientes operaciones de escritura:
Cada operación de escritura se pasa a bulkWrite() como un documento en un arreglo.
Ejemplo
El ejemplo en esta sección utiliza la colección pizzas:
db.pizzas.insertMany( [ { _id: 0, type: "pepperoni", size: "small", price: 4 }, { _id: 1, type: "cheese", size: "medium", price: 7 }, { _id: 2, type: "vegan", size: "large", price: 8 } ] )
El siguiente ejemplo de bulkWrite() ejecuta estas operaciones en la colección pizzas:
Agrega dos documentos con
insertOne.Actualiza un documento con
updateOne.Elimina un documento con
deleteOne.Reemplaza un documento con
replaceOne.
try { db.pizzas.bulkWrite( [ { insertOne: { document: { _id: 3, type: "beef", size: "medium", price: 6 } } }, { insertOne: { document: { _id: 4, type: "sausage", size: "large", price: 10 } } }, { updateOne: { filter: { type: "cheese" }, update: { $set: { price: 8 } } } }, { deleteOne: { filter: { type: "pepperoni"} } }, { replaceOne: { filter: { type: "vegan" }, replacement: { type: "tofu", size: "small", price: 4 } } } ] ) } catch( error ) { print( error ) }
Ejemplo de salida, que incluye un resumen de las operaciones completadas:
{ acknowledged: true, insertedCount: 2, insertedIds: { '0': 3, '1': 4 }, matchedCount: 2, modifiedCount: 2, deletedCount: 1, upsertedCount: 0, upsertedIds: {} }
Para más ejemplos, consulta Ejemplos de bulkWrite().
Estrategias para inserciones masivas en una colección fragmentada
Las grandes operaciones de inserción masiva, incluidas las inserciones iniciales de datos o la importación rutinaria de datos, pueden afectar el rendimiento de un clúster fragmentado. Para inserciones masivas, considera las siguientes estrategias:
Pre-dividir la colección
Si la colección particionada está vacía, entonces la colección tiene un único fragmento inicial, que se encuentra en una única partición. MongoDB debe entonces tomarse un tiempo para recibir los datos, crear divisiones y distribuir los fragmentos divididos entre las particiones disponibles. Para evitar este costo de rendimiento, puedes predividir la colección, como se describe en Dividir fragmentos en un clúster.
Escrituras desordenados en mongos
Para mejorar el rendimiento de escritura en clústeres fragmentados, use bulkWrite() con el parámetro opcional ordered establecido false en. puede intentar enviar las escrituras a variosmongos fragmentos simultáneamente. Para colecciones vacías, divida previamente la colección como se describe en "Dividir fragmentos en un clúster fragmentado".
Evita la limitación monotónica
Si la clave de fragmentación aumenta de manera monotónica durante una inserción, entonces todos los datos insertados van al último fragmento en la colección, que siempre terminará en un solo fragmento. Por lo tanto, la capacidad de inserción del clúster nunca superará la capacidad de inserción de ese único fragmento.
Si el volumen de la inserción es mayor que lo que puede procesar un solo fragmento, y si no se puede evitar que una clave de fragmentación aumente de forma monotónica, se deben considerar las siguientes modificaciones en la aplicación:
Invierta los bits binarios de la clave de fragmentación. Esto preserva la información y evita correlacionar el orden de inserción con una secuencia creciente de valores.
Intercambia las primeras y últimas palabras de 16 bits para "barajar" las inserciones.
Ejemplo
El siguiente ejemplo, en C++, intercambia la palabra de 16 bits inicial y final de los tipos BSON ObjectIds generados para que no aumenten de forma monotónica.
using namespace mongo; OID make_an_id() { OID x = OID::gen(); const unsigned char *p = x.getData(); swap( (unsigned short&) p[0], (unsigned short&) p[10] ); return x; } void foo() { // create an object BSONObj o = BSON( "_id" << make_an_id() << "x" << 3 << "name" << "jane" ); // now we may insert o into a sharded collection }
Tip
Claves de fragmentación para obtener información sobre cómo elegir una clave de fragmentación. También consulta Componentes internos de claves de fragmentación (en particular, Elegir una clave de fragmentación).