Overview
En esta guía, puede aprender a utilizar el controlador Rust para realizar operaciones masivas.
Las operaciones masivas realizan múltiples operaciones de escritura en uno o más espacios de nombres. Un espacio de nombres es una combinación del nombre de la base de datos y el nombre de la colección, en el formato <database>.<collection>Dado que realiza operaciones masivas en una instancia Client, puede realizar operaciones masivas en cualquier espacio de nombres del clúster al que acceda su cliente.
Puedes realizar operaciones masivas para reducir el número de llamadas al servidor. En lugar de enviar una solicitud para cada operación, las operaciones masivas ejecutan varias operaciones dentro de una sola acción.
Esta guía incluye las siguientes secciones:
Los datos demuestra presentan los datos de muestra que se utilizan en los ejemplos de operaciones masivas
Tipos de operaciones en bloque describe cómo utilizar los tipos
WriteModelpara realizar operaciones en bloque de inserción, reemplazo, actualizado y borradoEltipo de retorno describe el valor de retorno del
bulk_write()método y cómo acceder a la información sobre la operación masivaModificar comportamiento describe cómo modificar el comportamiento predeterminado del
bulk_write()métodoEscribir en espacios de nombres mixtos describe cómo realizar una operación masiva en múltiples espacios de nombres en una llamada de método
Información adicional proporciona enlaces a recursos y documentación de API para los tipos y métodos mencionados en esta guía.
Importante
Para realizar operaciones de escritura masiva, asegúrese de que su aplicación cumpla con los siguientes requisitos:
Está conectado a MongoDB Server versión 8.0 o posterior.
Estás utilizando la versión del controlador Rust 3.0 o posterior.
Datos de muestra
Los ejemplos de esta guía utilizan los siguientes documentos de muestra, que se almacenan en la colección mushrooms de la base de datos db:
let docs = vec![ doc! {"name" : "portobello", "color" : "brown", "edible" : true }, doc! {"name" : "chanterelle", "color" : "yellow", "edible" : true }, doc! {"name" : "oyster", "color" : "white", "edible" : true }, doc! {"name" : "fly agaric", "color" : "red", "edible" : false }, ];
También puedes usar tipos de estructuras personalizadas para representar tus datos de muestras. Para un ejemplo que realiza una operación por lotes usando Mushroom structs para modelar los mismos datos, consulta el Ejemplo de inserción de structs en esta página.
Tipos de operaciones masivas
Para realizar una operación de escritura masiva, pase una matriz de instancias de enumeración WriteModel al método bulk_write().
En esta sección, puede aprender cómo realizar las siguientes operaciones de escritura masiva definiendo sus tipos WriteModel correspondientes:
Tip
También puede realizar varios tipos de operaciones de escritura en una sola bulk_write() llamada al método. Para ver un ejemplo que pasa un UpdateOneModel y un InsertOneModel a la misma bulk_write() llamada, consulte el ejemplo "Modificar comportamiento" en esta guía.
Insert
Para realizar una inserción masiva, cree una instancia InsertOneModel para cada documento que desee insertar. A continuación, pase una lista de modelos al método bulk_write().
La siguiente tabla describe InsertOneModel campos que puedes configurar llamando a sus métodos de construcción correspondientes:
Campo | Descripción |
|---|---|
| The namespace on which the insert is performed. Type: Namespace |
| The document to insert. Type: Document |
Ejemplo de inserción de documentos
Este ejemplo realiza las siguientes acciones:
Especifica dos instancias
InsertOneModelen una matriz. CadaInsertOneModelrepresenta un documento que se insertará en el espacio de nombresdb.mushrooms.Pasa el arreglo de modelos al método
bulk_write().Imprime el número de documentos insertados.
let mushrooms: Collection<Document> = client.database("db").collection("mushrooms"); let models = vec![ InsertOneModel::builder() .namespace(mushrooms.namespace()) .document(doc! { "name": "lion's mane", "color": "white", "edible": true }) .build(), InsertOneModel::builder() .namespace(mushrooms.namespace()) .document(doc! { "name": "angel wing", "color": "white", "edible": false }) .build(), ]; let result = client.bulk_write(models).await?; println!("Inserted documents: {}", result.inserted_count);
Inserted documents: 2
Ejemplo de Insertar Estructuras
También puede modelar sus documentos mediante el uso de estructuras e insertar en masa instancias de estructuras en el espacio de nombres db.mushrooms.
Este ejemplo realiza la misma operación que el ejemplo Insertar documentos anterior, pero inserta instancias del siguiente Mushroom tipo de estructura:
struct Mushroom { name: String, color: String, edible: bool, }
El siguiente código utiliza el método insert_one_model() para construir un InsertOneModel a partir de cada instancia Mushroom y luego inserta ambos modelos en una operación masiva:
let mushrooms: Collection<Mushroom> = client.database("db").collection("mushrooms"); let lions_mane = Mushroom { name: "lion's mane".to_string(), color: "white".to_string(), edible: true, }; let angel_wing = Mushroom { name: "angel wing".to_string(), color: "white".to_string(), edible: false, }; let lions_mane_model = mushrooms.insert_one_model(lions_mane)?; let angel_wing_model = mushrooms.insert_one_model(angel_wing)?; let result = client.bulk_write([lions_mane_model, angel_wing_model]).await?; println!("Inserted documents: {}", result.inserted_count);
Inserted documents: 2
Tip
Para obtener más información sobre los tipos de estructuras personalizadas y la serialización en el controlador Rust, consulte la guía en Modelado y serialización de datos.
Reemplaza
Para realizar una operación de reemplazo masivo, cree una instancia ReplaceOneModel para cada documento que desee reemplazar. Luego, pase una lista de modelos al método bulk_write().
La siguiente tabla describe ReplaceOneModel campos que puedes configurar llamando a sus métodos de construcción correspondientes:
Campo | Descripción |
|---|---|
| The namespace on which the operation is performed. Type: Namespace |
| The filter that matches the document you want to replace. Type: Document |
| The replacement document. Type: Document |
| (Optional) The collation to use when sorting results. To learn more about collations,
see the Collations guide. Type: Document |
| (Optional) The index to use for the operation. To learn more about
indexes, see the Indexes guide. Type: Bson |
| (Optional) Whether a new document is created if no document matches the filter. By default, this field is set to false.Type: bool |
Ejemplo
Este ejemplo realiza las siguientes acciones:
Especifica dos instancias
ReplaceOneModelen un arreglo. Las instancias deReplaceOneModelcontienen instrucciones para reemplazar documentos que representan hongos en el espacio de nombresdb.mushrooms.Pasa el arreglo de modelos al método
bulk_write().Imprime el número de documentos modificados.
let mushrooms: Collection<Document> = client.database("db").collection("mushrooms"); let models = vec![ ReplaceOneModel::builder() .namespace(mushrooms.namespace()) .filter(doc! { "name": "portobello" }) .replacement(doc! { "name": "cremini", "color": "brown", "edible": true }) .build(), ReplaceOneModel::builder() .namespace(mushrooms.namespace()) .filter(doc! { "name": "oyster" }) .replacement(doc! { "name": "golden oyster", "color": "yellow", "edible": true }) .upsert(true) .build(), ]; let result = client.bulk_write(models).await?; println!("Modified documents: {}", result.modified_count);
Modified documents: 2
Update
Para realizar una actualización masiva, cree una instancia UpdateOneModel o UpdateManyModel para cada actualización que desee realizar. Luego, pase una lista de modelos al método bulk_write(). Un UpdateOneModel actualiza solo un documento que coincide con un filtro, mientras que un UpdateManyModel actualiza todos los documentos que coinciden con un filtro.
La siguiente tabla describe los campos UpdateOneModel y UpdateManyModel que puede configurar llamando a sus métodos de generación correspondientes:
Campo | Descripción |
|---|---|
| The namespace on which the operation is performed. Type: Namespace |
| The filter that matches one or more documents you want to update. When specified in an UpdateOneModel,
only the first matching document will be updated. When specified in an UpdateManyModel, all
matching documents will be updated.Type: Document |
| The update to perform. Type: UpdateModifications |
| (Optional) A set of filters specifying which array elements an update applies to if you are updating an
array-valued field. Type: Array |
| (Optional) The collation to use when sorting results. To learn more about collations,
see the Collations guide. Type: Document |
| (Optional) The index to use for the operation. To learn more about
indexes, see the Indexes guide. Type: Bson |
| (Optional) Whether a new document is created if no document matches the filter.
By default, this field is set to false.Type: bool |
Ejemplo
Este ejemplo realiza las siguientes acciones:
Especifica una instancia
UpdateOneModely unaUpdateManyModelen una matriz. Estos modelos contienen instrucciones para actualizar los documentos que representan hongos en el espacio de nombresdb.mushrooms.Pasa el arreglo de modelos al método
bulk_write().Imprime el número de documentos modificados.
let mushrooms: Collection<Document> = client.database("db").collection("mushrooms"); let models = vec![ WriteModel::UpdateOne( UpdateOneModel::builder() .namespace(mushrooms.namespace()) .filter(doc! { "name": "fly agaric" }) .update(doc! { "$set": { "name": "fly amanita" } }) .upsert(true) .build(), ), WriteModel::UpdateMany( UpdateManyModel::builder() .namespace(mushrooms.namespace()) .filter(doc! { "color": "yellow" }) .update(doc! { "$set": { "color": "yellow/orange" } }) .build(), ), ]; let result = client.bulk_write(models).await?; println!("Modified documents: {}", result.modified_count);
Modified documents: 2
Borrar
Para realizar una eliminación masiva, cree una instancia DeleteOneModel o DeleteManyModel para cada operación de eliminación. A continuación, pase una lista de modelos al método bulk_write(). Un DeleteOneModel elimina solo un documento que coincide con un filtro, mientras que un DeleteManyModel elimina todos los documentos que coinciden con un filtro.
La siguiente tabla describe los campos DeleteOneModel y DeleteManyModel que puede configurar llamando a sus métodos de generación correspondientes:
Campo | Descripción |
|---|---|
| The namespace on which the operation is performed. Type: Namespace |
| The filter that matches one or more documents you want to delete. When specified in a DeleteOneModel,
only the first matching document will be deleted. When specified in a DeleteManyModel, all
matching documents will be deleted.Type: Document |
| (Optional) The collation to use when sorting results. To learn more about collations,
see the Collations guide. Type: Document |
| (Optional) The index to use for the operation. To learn more about
indexes, see the Indexes guide. Type: Bson |
Ejemplo
Este ejemplo realiza las siguientes acciones:
Especifica una instancia
DeleteOneModely unaDeleteManyModelen una matriz. Estos modelos contienen instrucciones para eliminar documentos que representan hongos en el espacio de nombresdb.mushrooms.Pasa el arreglo de modelos al método
bulk_write().Imprime el número de documentos eliminados.
let mushrooms: Collection<Document> = client.database("db").collection("mushrooms"); let models = vec![ WriteModel::DeleteOne( DeleteOneModel::builder() .namespace(mushrooms.namespace()) .filter(doc! { "color": "red" }) .build(), ), WriteModel::DeleteMany( DeleteManyModel::builder() .namespace(mushrooms.namespace()) .filter(doc! { "edible": true }) .build(), ), ]; let result = client.bulk_write(models).await?; println!("Deleted documents: {}", result.deleted_count);
Deleted documents: 4
Tipo de retorno
El método bulk_write() devuelve una instancia de estructura SummaryBulkWriteResult desde la cual puede acceder a información sobre su operación masiva.
El tipo SummaryBulkWriteResult tiene los siguientes campos:
inserted_count: el número de documentos insertadosmatched_count: el número de documentos coincididos.modified_count:el número de documentos actualizadosupserted_count: el número de documentos insertadosdeleted_count:el número de documentos eliminados
También puede usar el método verbose_results() para ver información detallada sobre cada operación. El método verbose_results() devuelve una instancia de estructura VerboseBulkWriteResult, que contiene los siguientes campos:
delete_results:los resultados de cada operación de eliminación exitosainsert_results:los resultados de cada operación de inserción exitosaupdate_results:los resultados de cada operación de actualización exitosasummary:un resumen de los resultados de cada tipo de operación
El siguiente ejemplo encadena el método verbose_results() al método bulk_write() e imprime los resultados de las operaciones de actualización y eliminación:
let models = vec![ WriteModel::DeleteOne( DeleteOneModel::builder() .namespace(mushrooms.namespace()) .filter(doc! { "name": "oyster" }) .build(), ), WriteModel::UpdateOne( UpdateOneModel::builder() .namespace(mushrooms.namespace()) .filter(doc! { "name": "chanterelle" }) .update(doc! { "$set": { "season": ["July", "August", "September"] } }) .build(), ), ]; let result = client.bulk_write(models).verbose_results().await?; println!( "Update results: {:?}\nDelete results: {:?}\n", result.update_results, result.delete_results );
Update results: {1: UpdateResult { matched_count: 1, modified_count: 1, upserted_id: None }} Delete results: {0: DeleteResult { deleted_count: 1 }}
Modificar el comportamiento
Puede modificar el comportamiento del método bulk_write() estableciendo los valores de campo BulkWriteOptions. Para establecer estos campos de estructura, encadene los métodos correspondientes de los campos al método bulk_write().
La estructura BulkWriteOptions contiene los siguientes campos:
Campo | Descripción | Valor por defecto |
|---|---|---|
| Whether the operations run in the order in which they were specified. When set to true, one failed operation prevents subsequent operations from running.When set to false, the server continues to attempt write operations if one fails.Type: bool |
|
| Whether document-level validation is bypassed. Type: bool |
|
| An arbitrary comment to help trace the operation through the database profiler, currentOp,
and logs. Type: Bson |
|
| A map of parameter names and values to apply to all operations within the bulk write.
Values must be constant or closed expressions that do not reference document fields. Type: Document |
|
| The write concern to use for this bulk operation. Type: WriteConcern | Hereda la preocupación de escritura del espacio de nombres |
Ejemplo
Este ejemplo intenta realizar operaciones de actualización e inserción en la colección mushrooms. El siguiente código establece el campo ordered en false encadenando el método ordered() con el método bulk_write():
let mushrooms: Collection<Document> = client.database("db").collection("mushrooms"); let models = vec![ WriteModel::UpdateOne(UpdateOneModel::builder() .namespace(mushrooms.namespace()) .filter(doc! { "name": "portobello" }) .update(doc! { "$set": { "_id": 123 } }) .upsert(true) .build()), WriteModel::InsertOne(InsertOneModel::builder() .namespace(mushrooms.namespace()) .document(doc! { "name": "reishi", "color": "red/brown", "edible": true }) .build()), ]; let result = client.bulk_write(models).ordered(false).await?; println!( "Inserted documents: {}\nDeleted documents: {}", result.inserted_count, result.deleted_count );
Error: Error { kind: BulkWrite(BulkWriteError { write_concern_errors: [], write_errors: {0: WriteError { code: 66, code_name: None, message: "Plan executor error during update :: caused by :: Performing an update on the path '_id' would modify the immutable field '_id'", details: None }}, partial_result: Some(Summary(SummaryBulkWriteResult { inserted_count: 1, matched_count: 0, modified_count: 0, upserted_count: 0, deleted_count: 0 })) }), labels: ... }
El campo _id es inmutable y no se puede modificar en una operación de actualización. Dado que UpdateOneModel incluye instrucciones para actualizar este campo, la operación masiva devuelve BulkWriteError y solo realiza la operación de inserción. Si se establece el campo ordered en true, el controlador no intenta realizar ninguna operación posterior a la operación de actualización fallida y no inserta ningún documento.
Escribir en espacios de nombres mixtos
Los ejemplos anteriores de esta página realizan operaciones masivas en el espacio de nombres db.mushrooms. Sin embargo, se pueden realizar operaciones masivas de escritura en varios espacios de nombres con una sola llamada de método.
El siguiente ejemplo inserta un documento en el espacio de nombres ingredients.sweet y un documento en el espacio de nombres meals.dessert:
let sweet: Collection<Document> = client .database("ingredients") .collection("sweet"); let dessert: Collection<Document> = client .database("meals") .collection("dessert"); let models = vec![ InsertOneModel::builder() .namespace(sweet.namespace()) .document(doc! { "name": "brown sugar", "price": 3.99 }) .build(), InsertOneModel::builder() .namespace(dessert.namespace()) .document(doc! { "name": "banana bread", "cook_time": 75 }) .build(), ]; let result = client.bulk_write(models).await?; println!("Inserted documents: {}", result.inserted_count);
Inserted documents: 2
Información Adicional
Para obtener más información sobre operaciones masivas, consulte Operaciones de escritura masiva en el manual del servidor.