Overview
In this guide, you can learn how to use the Rust driver to perform bulk operations.
Bulk operations perform multiple write operations against one or more
namespaces. A namespace is a combination of the database name and
the collection name, in the format <database>.<collection>. Since
you perform bulk operations on a Client instance, you can perform
bulk operations against any namespace in the cluster accessed by your client.
You can perform bulk operations to reduce the number of calls to the server. Instead of sending a request for each operation, bulk operations perform multiple operations within one action.
This guide includes the following sections:
- Sample Data presents the sample data that is used by the bulk operation examples 
- Bulk Operation Types describes how to use - WriteModeltypes to perform bulk insert, replace, update, and delete operations
- Return Type describes the return value of the - bulk_write()method and how to access information about the bulk operation
- Modify Behavior describes how to modify the default behavior of the - bulk_write()method
- Write to Mixed Namespaces describes how to perform a bulk operation on multiple namespaces in one method call 
- Additional Information provides links to resources and API documentation for types and methods mentioned in this guide 
Important
To perform bulk write operations, ensure that your application meets the following requirements:
- You are connected to MongoDB Server version 8.0 or later. 
- You are using Rust driver version 3.0 or later. 
Sample Data
The examples in this guide use the following sample documents, which
are stored in the mushrooms collection in the db database:
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 }, ]; 
You can also use custom struct types to represent your sample data. For
an example that performs a bulk operation by using Mushroom structs
to model the same data, see the Insert Structs Example on this
page.
Bulk Operation Types
To perform a bulk write operation, pass an array of WriteModel enum instances to the
bulk_write() method.
In this section, you can learn how to perform the following bulk write operations
by defining their corresponding WriteModel types:
Tip
You can also perform multiple types of write operations in a single bulk_write()
method call. To view an example that passes an UpdateOneModel and an InsertOneModel to
the same bulk_write() call, see the Modify Behavior example
in this guide.
Insert
To perform a bulk insert operation, create an InsertOneModel instance for each document
you want to insert. Then, pass a list of models to the bulk_write() method.
The following table describes InsertOneModel fields that you can set by calling their
corresponding builder methods:
| Field | Description | 
|---|---|
| 
 | The namespace on which the insert is performed. Type:  Namespace | 
| 
 | The document to insert. Type:  Document | 
Insert Documents Example
This example performs the following actions:
- Specifies two - InsertOneModelinstances in an array. Each- InsertOneModelrepresents a document to be inserted into the- db.mushroomsnamespace.
- Passes the array of models to the - bulk_write()method.
- Prints the number of inserted documents. 
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 
Insert Structs Example
You can also model your documents by using structs and bulk insert struct instances into the
db.mushrooms namespace.
This example performs the same operation as the preceding Insert Documents Example but
inserts instances of the following Mushroom struct type:
struct Mushroom {     name: String,     color: String,     edible: bool, } 
The following code uses the insert_one_model() method to construct an InsertOneModel
from each Mushroom instance, then inserts both models in a bulk operation:
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
To learn more about custom struct types and serialization in the Rust driver, see the guide on Data Modeling and Serialization.
Replace
To perform a bulk replace operation, create a ReplaceOneModel instance for each document
you want to replace. Then, pass a list of models to the bulk_write() method.
The following table describes ReplaceOneModel fields that you can set by calling their
corresponding builder methods:
| Field | Description | 
|---|---|
| 
 | 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 | 
Example
This example performs the following actions:
- Specifies two - ReplaceOneModelinstances in an array. The- ReplaceOneModelinstances contain instructions to replace documents representing mushrooms in the- db.mushroomsnamespace.
- Passes the array of models to the - bulk_write()method.
- Prints the number of modified documents. 
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
To perform a bulk update operation, create an UpdateOneModel or UpdateManyModel
instance for each update you want to make. Then, pass a list of models to the bulk_write() method.
An UpdateOneModel updates only one document that matches a filter, while an UpdateManyModel
updates all documents that match a filter.
The following table describes UpdateOneModel and UpdateManyModel fields that you can set
by calling their corresponding builder methods:
| Field | Description | 
|---|---|
| 
 | 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 anUpdateManyModel, 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 | 
Example
This example performs the following actions:
- Specifies an - UpdateOneModeland an- UpdateManyModelinstance in an array. These models contain instructions to update documents representing mushrooms in the- db.mushroomsnamespace.
- Passes the array of models to the - bulk_write()method.
- Prints the number of modified documents. 
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 
Delete
To perform a bulk delete operation, create a DeleteOneModel or DeleteManyModel
instance for each delete operation. Then, pass a list of models to the bulk_write() method.
A DeleteOneModel deletes only one document that matches a filter, while a DeleteManyModel
deletes all documents that match a filter.
The following table describes DeleteOneModel and DeleteManyModel fields that you can set
by calling their corresponding builder methods:
| Field | Description | 
|---|---|
| 
 | 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 aDeleteManyModel, 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 | 
Example
This example performs the following actions:
- Specifies a - DeleteOneModeland a- DeleteManyModelinstance in an array. These models contain instructions to delete documents representing mushrooms in the- db.mushroomsnamespace.
- Passes the array of models to the - bulk_write()method.
- Prints the number of deleted documents. 
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 
Return Type
The bulk_write() method returns a SummaryBulkWriteResult struct instance from which
you can access information about your bulk operation.
The SummaryBulkWriteResult type has the following fields:
- inserted_count: the number of inserted documents
- matched_count: the number of matched documents
- modified_count: the number of updated documents
- upserted_count: the number of upserted documents
- deleted_count: the number of deleted documents
You can also use the verbose_results() method to see detailed information about each
operation. The verbose_results() method returns a VerboseBulkWriteResult struct
instance, which has the following fields:
- delete_results: the results of each successful delete operation
- insert_results: the results of each successful insert operation
- update_results: the results of each successful update operation
- summary: a summary of the results of each operation type
The following example chains the verbose_results() method to the bulk_write() method
and prints the results of the update and delete operations:
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 }} 
Modify Behavior
You can modify the behavior of the bulk_write() method by setting BulkWriteOptions field
values. To set these struct fields, chain the fields' corresponding methods to the bulk_write()
method.
The BulkWriteOptions struct contains the following fields:
| Field | Description | Default Value | 
|---|---|---|
| 
 | 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 | Inherits the namespace's write concern | 
Example
This example attempts to perform update and insert operations on the mushrooms
collection. The following code sets the ordered field to false by chaining
the ordered() method to the bulk_write() method:
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: ... } 
The _id field is immutable and cannot be changed in an update operation. Since the UpdateOneModel
includes instructions to update this field, the bulk operation returns a BulkWriteError and performs
only the insert operation. If you set the ordered field to true, the driver does not attempt any
subsequent operations after the unsuccessful update operation, and the driver does not insert any
documents.
Write to Mixed Namespaces
The preceding examples on this page perform bulk operations on the db.mushrooms namespace. However,
you can perform bulk writes on multiple namespaces in a single method call.
The following example inserts one document into the ingredients.sweet namespace and one document into
the meals.dessert namespace:
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 
Additional Information
To learn more about bulk operations, see Bulk Write Operations in the Server manual.