Join us at MongoDB.local London on 7 May to unlock new possibilities for your data. Use WEB50 to save 50%.
Register now >
Docs Menu
Docs Home
/ /

Operaciones masivas

En esta guía, puedes aprender a utilizar el controlador de Rust para realizar operaciones masivas.

Las operaciones masivas realizan múltiples operaciones de escritura en uno o más espacios de nombres. Un namespace 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:

  • Datos de muestra presenta los datos de muestra que se utilizan en los ejemplos de operaciones masivas

  • Tipos de operaciones en bloque describe cómo utilizar los tipos WriteModel para realizar operaciones en bloque de inserción, reemplazo, actualizado y borrado

  • Tipo de retorno describe el valor de retorno del método bulk_write() y cómo acceder a la información sobre la operación masiva.

  • Modificar comportamiento describe cómo modificar el comportamiento predeterminado del bulk_write() método

  • Escribir 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 la 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.

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.

Para realizar una operación de escritura masiva, pasa un arreglo de instancias del enum WriteModel al método bulk_write().

En esta sección, puedes aprender cómo realizar las siguientes operaciones de guardado masivo definiendo sus respectivos tipos WriteModel:

Tip

También puede realizar varios tipos de operaciones de guardar en una única llamada al método bulk_write(). Para ver un ejemplo que pase un UpdateOneModel y un InsertOneModel a la misma llamada bulk_write(), consulte el Ejemplo de modificación de conducta en esta guía.

Para realizar una operación de inserción masiva, crea una instancia de InsertOneModel para cada documento que desees insertar. Luego, 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

namespace

The namespace on which the insert is performed.
Type: Namespace

document

The document to insert.
Type: Document

Este ejemplo realiza las siguientes acciones:

  • Especifica dos instancias InsertOneModel en una matriz. Cada InsertOneModel representa un documento que se insertará en el espacio de nombres db.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

También puedes modelar tus documentos utilizando struct y realizar una inserción masiva de instancias de struct en el namespace db.mushrooms.

Este ejemplo realiza la misma operación que Ejemplo de inserción de documentos precedente, pero inserta instancias del siguiente tipo de estructura Mushroom:

#[derive(Serialize)]
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 de Mushroom, 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.

Para realizar una operación de reemplazo masivo, cree una instancia de 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

namespace

The namespace on which the operation is performed.
Type: Namespace

filter

The filter that matches the document you want to replace.
Type: Document

replacement

The replacement document.
Type: Document

collation

(Optional) The collation to use when sorting results. To learn more about collations, see the Collations guide.
Type: Document

hint

(Optional) The index to use for the operation. To learn more about indexes, see the Indexes guide.
Type: Bson

upsert

(Optional) Whether a new document is created if no document matches the filter.
By default, this field is set to false.
Type: bool

Este ejemplo realiza las siguientes acciones:

  • Especifica dos instancias ReplaceOneModel en un arreglo. Las instancias de ReplaceOneModel contienen instrucciones para reemplazar documentos que representan hongos en el espacio de nombres db.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

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

namespace

The namespace on which the operation is performed.
Type: Namespace

filter

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

update

The update to perform.
Type: UpdateModifications

array_filters

(Optional) A set of filters specifying which array elements an update applies to if you are updating an array-valued field.
Type: Array

collation

(Optional) The collation to use when sorting results. To learn more about collations, see the Collations guide.
Type: Document

hint

(Optional) The index to use for the operation. To learn more about indexes, see the Indexes guide.
Type: Bson

upsert

(Optional) Whether a new document is created if no document matches the filter. By default, this field is set to false.
Type: bool

Este ejemplo realiza las siguientes acciones:

  • Especifica una instancia UpdateOneModel y una UpdateManyModel en un arreglo. Estos modelos contienen instrucciones para actualizar documentos que representan setas en el espacio de nombres db.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

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

namespace

The namespace on which the operation is performed.
Type: Namespace

filter

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

collation

(Optional) The collation to use when sorting results. To learn more about collations, see the Collations guide.
Type: Document

hint

(Optional) The index to use for the operation. To learn more about indexes, see the Indexes guide.
Type: Bson

Este ejemplo realiza las siguientes acciones:

  • Especifica una instancia DeleteOneModel y una DeleteManyModel en una matriz. Estos modelos contienen instrucciones para eliminar documentos que representan hongos en el espacio de nombres db.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

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 insertados

  • matched_count: el número de documentos coincididos.

  • modified_countla cantidad de documentos actualizados

  • upserted_countNúmero de documentos actualizados/insertados

  • deleted_count:el número de documentos eliminados

También puede utilizar el método verbose_results() para ver información detallada sobre cada operación. El método verbose_results() devuelve una instancia de la estructura VerboseBulkWriteResult, que tiene los siguientes campos:

  • delete_results: los resultados de cada operación de eliminación exitosa

  • insert_results:los resultados de cada operación de inserción exitosa

  • update_results:los resultados de cada operación de actualización exitosa

  • summaryun 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 }}

Puede modificar el comportamiento del método bulk_write() ajustando los valores de los campos BulkWriteOptions. Para establecer estos campos de struct, 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

ordered

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

true

bypass_document_validation

Whether document-level validation is bypassed.
Type: bool

false

comment

An arbitrary comment to help trace the operation through the database profiler, currentOp, and logs.
Type: Bson

None

let_vars

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

None

write_concern

The write concern to use for this bulk operation.
Type: WriteConcern

Hereda la preocupación de escritura del espacio de nombres

Este ejemplo intenta realizar operaciones de actualización e inserción en la colección mushrooms. El siguiente código establece el campo ordered a false encadenando el método ordered() al 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 cambiar en una operación de actualización. Dado que la UpdateOneModel incluye instrucciones para actualizar este campo, la operación masiva devuelve una BulkWriteError y realiza solo la operación de inserción. Si estableces el campo ordered en true, el driver no intentará ninguna operación posterior tras la operación de actualización fallida, y el driver no insertará ningún documento.

Los ejemplos anteriores en esta página realizan operaciones masivas en el namespace db.mushrooms. Sin embargo, puedes realizar guardados masivos en varios namespace en una sola llamada de método.

El siguiente ejemplo inserta un documento en el namespace ingredients.sweet y uno en el namespace 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

Para obtener más información sobre las operaciones por lotes, consulta Operaciones de escritura por lotes en el manual del servidor.

Volver

Borrar

En esta página