Docs Menu
Docs Home
/ /

Operaciones masivas

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 WriteModel para realizar operaciones en bloque de inserción, reemplazo, actualizado y borrado

  • Eltipo de retorno describe el valor de retorno del bulk_write() método 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 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, 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.

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

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 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:

#[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 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.

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

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 una matriz. Estos modelos contienen instrucciones para actualizar los 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![
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_count:el número de documentos actualizados

  • upserted_count: el número de documentos insertados

  • deleted_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 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

  • summary: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 }}

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

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 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.

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

Para obtener más información sobre operaciones masivas, consulte Operaciones de escritura masiva en el manual del servidor.

Volver

Borrar

En esta página