Para agentes de IA: hay un índice de documentación disponible en https://www.mongodb.com/es/docs/llms.txt — versiones en markdown de todas las páginas están disponibles agregando .md a cualquier ruta URL.
Docs Menu

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>. Como realizas operaciones masivas en una instancia Client, puedes realizar operaciones masivas en cualquier namespace en el clúster al que acceda tu 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 por defecto del método bulk_write()

  • Guardar en espacios de nombres mixtos describe cómo realizar una operación masiva en varios espacios de nombres en una sola 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 en lote, asegúrate de que tu aplicación cumpla con los siguientes requisitos:

  • Está conectado a MongoDB Server versión 8.0 o posterior.

  • Estás usando la versión 3.0 o posterior del controlador Rust.

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 establecer llamando a sus respectivos métodos constructores:

Campo
Descripción

namespace

El namespace en el que se realiza la inserción.
Tipo: Namespace

document

El documento a insertar.
Tipo: Document

Este ejemplo realiza las siguientes acciones:

  • Especifica dos instancias de InsertOneModel en un arreglo. Cada InsertOneModel representa un documento que se va a 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 saber más sobre tipos de struct personalizados y serialización en el driver de Rust, consulta la guía sobre Modelado de Datos y Serialización.

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 establecer llamando a sus respectivos métodos constructores:

Campo
Descripción

namespace

El namespace en el que se realiza la operación.
Tipo: Namespace

filter

El filtro que coincide con el documento que deseas reemplazar.
Tipo: Document

replacement

El documento de sustitución.
Tipo: Document

collation

(Opcional) La intercalación que se utilizará al ordenar los resultados. Para obtener más información sobre las intercalaciones, consulte la guía Intercalaciones.
Tipo: Document

hint

(Opcional) El índice que se utilizará para la operación. Para obtener más información sobre los índices, consulte la guía de Índices.
Tipo: Bson

upsert

(Opcional) si se crea un nuevo documento si ningún documento coincide con el filtro.
Por defecto, este campo está configurado en false.
Tipo: 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 la cantidad 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 operación de actualización masiva, crea una instancia de UpdateOneModel o UpdateManyModel para cada actualización que desees realizar. Luego, pasa una lista de modelos al método bulk_write(). Un UpdateOneModel actualiza únicamente un documento que coincida con un filtro, mientras que un UpdateManyModel actualiza todos los documentos que coincidan con un filtro.

La siguiente tabla describe los campos UpdateOneModel y UpdateManyModel que puedes establecer llamando a sus métodos desarrolladores correspondientes:

Campo
Descripción

namespace

El namespace en el que se realiza la operación.
Tipo: Namespace

filter

El filtro que coincide con uno o más documentos que deseas actualizar. Cuando se especifica en un UpdateOneModel, solo se actualizará el primer documento que coincida. Cuando se especifica en un UpdateManyModel, se actualizarán todos los documentos que coincidan.
Tipo: Document

update

La actualización a realizar.
Tipo: UpdateModifications

array_filters

(Opcional) Un conjunto de filtros que especifican a qué elementos de un arreglo se aplica una actualización si se está actualizando un campo con valores de tipo arreglo.
Tipo: Array

collation

(Opcional) La intercalación que se utilizará al ordenar los resultados. Para obtener más información sobre las intercalaciones, consulte la guía Intercalaciones.
Tipo: Document

hint

(Opcional) El índice que se utilizará para la operación. Para obtener más información sobre los índices, consulte la guía de Índices.
Tipo: Bson

upsert

(Opcional) Si se crea un nuevo documento si ningún documento coincide con el filtro. Por defecto, este campo está configurado en false.
Tipo: 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 la cantidad 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 operación de eliminación masiva, cree una instancia DeleteOneModel o DeleteManyModel para cada operación de eliminación. Luego, pasa una lista de modelos al método bulk_write(). Un DeleteOneModel elimina solo un documento que coincida con un filtro, mientras que un DeleteManyModel elimina todos los documentos que coincidan con un filtro.

La siguiente tabla describe los campos DeleteOneModel y DeleteManyModel que puedes establecer llamando a sus métodos desarrolladores correspondientes:

Campo
Descripción

namespace

El namespace en el que se realiza la operación.
Tipo: Namespace

filter

El filtro que coincide con uno o más documentos que deseas eliminar. Cuando se especifique en un DeleteOneModel, solo se borrará el primer documento coincidente. Cuando se especifica en un DeleteManyModel, se eliminarán todos los documentos que coincidan.
Tipo: Document

collation

(Opcional) La intercalación que se utilizará al ordenar los resultados. Para obtener más información sobre las intercalaciones, consulte la guía Intercalaciones.
Tipo: Document

hint

(Opcional) El índice que se utilizará para la operación. Para obtener más información sobre los índices, consulte la guía de Índices.
Tipo: Bson

Este ejemplo realiza las siguientes acciones:

  • Especifica una instancia DeleteOneModel y una DeleteManyModel en un arreglo. Estos modelos contienen instrucciones para borrar documentos que representan hongos en el namespace 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() retorna una instancia de struct SummaryBulkWriteResult desde la cual se puede acceder a la información sobre la 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_countnú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

Si las operaciones se ejecutan en el orden en que se especificaron.
Cuando se establece en true, una operación fallida impide que se ejecuten las operaciones posteriores.
Cuando se establece en false, el servidor continúa intentando operaciones de guardar si una falla.
Tipo: bool

true

bypass_document_validation

Si se omite la validación a nivel de documento.
Tipo: bool

false

comment

Un comentario arbitrario para ayudar a rastrear la operación a través del perfilador de base de datos, currentOp y los registros.
Tipo: Bson

None

let_vars

Un mapa de nombres y valores de parámetros para aplicar a todas las operaciones dentro del guardado masivo. Los valores deben ser expresiones constantes o cerradas que no hagan referencia a campos de documentos.
Tipo: Document

None

write_concern

El nivel de confirmación de escritura (write concern) que se utilizará para esta operación masiva.
Tipo: WriteConcern

Hereda el nivel de confirmación de escritura (write concern) del namespace

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.

Para aprender más sobre cualquiera de los métodos o tipos analizados en esta guía, consulta la siguiente documentación de API: