Overview
In this guide, you can learn how to use bulk operations in the Java driver.
To perform a single create, replace, update, or delete operation, you can use
the corresponding method. For example, to insert one document and replace one
document, you can use the insertOne() and replaceOne() methods. When you
use these methods, your client makes one call to the database for each operation.
By using a bulk write operation, you can perform multiple write operations in fewer database calls. You can perform bulk write operations at the following levels:
Collection: You can use the
MongoCollection.bulkWrite()method to perform bulk write operations on a single collection. In this method, each kind of write operation requires at least one database call. For example,MongoCollection.bulkWrite()puts multiple update operations in one call, but makes two separate calls to the database for an insert operation and a replace operation.Client: If your application connects to MongoDB Server version 8.0 or later, you can use the
MongoClient.bulkWrite()method to perform bulk write operations on multiple collections and databases in the same cluster. This method performs all write operations in one database call.
Collection Bulk Write
Bulk write operations contain one or more write operations. To perform a bulk
write operation at the collection level, pass a List of WriteModel
documents to the MongoCollection.bulkWrite() method. A WriteModel is a
model that represents a write operation.
The MongoCollection.bulkWrite() method performs each kind of write
operation in a separate database call. For example, when you pass DeleteOneModel,
DeleteManyModel, and ReplaceOneModel objects to the method, it performs
two calls: one for the delete operations and one for the replace operation.
Note
When the client splits operations into separate database calls, it might reorder operations for efficiency if the bulk write operation is not ordered. To learn more about operation execution order, see the Order of Execution section.
The following sections show how to create and use each WriteModel
document. The examples in each section use the following documents in the
people collection:
{ "_id": 1, "name": "Karen Sandoval", "age": 31 } { "_id": 2, "name": "William Chin", "age": 54 } { "_id": 8, "name": "Shayla Ray", "age": 20 }
For more information about the methods and classes mentioned in this section, see the following API documentation:
Insert Operation
To perform an insert operation, create an InsertOneModel specifying
the document you want to insert. To insert multiple documents, you must
create an InsertOneModel for each document you want to insert.
Example
The following example creates an InsertOneModel for two documents
describing people:
InsertOneModel<Document> juneDoc = new InsertOneModel<>(new Document("name", "June Carrie") .append("age", 17)); InsertOneModel<Document> kevinDoc = new InsertOneModel<>(new Document("name", "Kevin Moss") .append("age", 22));
Important
When performing a bulkWrite(), the InsertOneModel cannot
insert a document with an _id that already exists in the
collection. Instead, the method throws a MongoBulkWriteException.
The following example tries to insert two documents where the _id is
1 and 3:
try { List<WriteModel<Document>> bulkOperations = new ArrayList<>(); // Creates instructions to insert documents InsertOneModel<Document> doc1 = new InsertOneModel<>(new Document("_id", 1)); InsertOneModel<Document> doc3 = new InsertOneModel<>(new Document("_id", 3)); bulkOperations.add(doc1); bulkOperations.add(doc3); // Runs a bulk write operation for the specified insert WriteModels collection.bulkWrite(bulkOperations); // Prints a message if any exceptions occur during the bulk write operation } catch (MongoBulkWriteException e){ System.out.println("A MongoBulkWriteException occurred with the following message: " + e.getMessage()); }
The following shows the output of the preceding code:
A MongoBulkWriteException occurred with the following message: Bulk write operation error on server sample-shard-00-02.pw0q4.mongodb.net:27017. Write errors: [BulkWriteError{index=0, code=11000, message='E11000 duplicate key error collection: crudOps.bulkWrite index: _id_ dup key: { _id: 1 }', details={}}].
To see why the document with the _id of 3 didn't insert, see
the Order of Execution section.
For more information about the methods and classes mentioned in this section, see the InsertOneModel API documentation.
Replace Operation
To perform a replace operation, create a ReplaceOneModel specifying
a query filter for the document you want to replace with the replacement
document.
Important
When performing a bulkWrite(), the ReplaceOneModel cannot
make changes to a document that violate unique index constraints on
the collection, and the model does not replace a document if there
are no matches to your query filter.
Example
The following example creates a ReplaceOneModel to
replace a document where the _id is 1 with a document that
contains an added location field:
ReplaceOneModel<Document> celineDoc = new ReplaceOneModel<>( Filters.eq("_id", 1), new Document("name", "Celine Stork") .append("location", "San Diego, CA"));
If multiple documents match the query filter specified in
the ReplaceOneModel instance, the operation replaces the first
result. You can specify a sort in a ReplaceOptions instance to apply
an order to matched documents before the server performs the replace
operation, as shown in the following code:
ReplaceOptions options = ReplaceOptions.sort(Sorts.ascending("_id"));
For more information about the methods and classes mentioned in this section, see the following resources:
ReplaceOneModel API documentation
ReplaceOptions API documentation
Unique indexes Server Manual Explanation
Update Operation
To perform an update operation, create an UpdateOneModel or an
UpdateManyModel specifying a query filter for documents you want to
update with what the updates are.
The UpdateOneModel updates the first document that matches your query
filter and the UpdateManyModel updates all the documents that
match your query filter.
Important
When performing a bulkWrite(), the UpdateOneModel and
UpdateManyModel cannot make changes to a document that violate
unique index constraints on the collection, and the models do not
update any documents if there are no matches to your query filter.
Example
The following example creates an UpdateOneModel to update
the age field in a document where the _id is 2:
UpdateOneModel<Document> updateDoc = new UpdateOneModel<>( Filters.eq("_id", 2), Updates.set("age", 31));
If multiple documents match the query filter specified in
the UpdateOneModel instance, the operation updates the first
result. You can specify a sort in an UpdateOptions instance to apply
an order to matched documents before the server performs the update
operation, as shown in the following code:
UpdateOptions options = UpdateOptions.sort(Sorts.ascending("_id"));
For more information about the methods and classes mentioned in this section, see the following resources:
UpdateOneModel API documentation
UpdateManyModel API documentation
UpdateOptions API documentation
unique indexes Server Manual Explanation
Delete Operation
To perform a delete operation, create a DeleteOneModel or a
DeleteManyModel specifying a query filter for documents you want to
delete.
The DeleteOneModel deletes the first document that matches your query
filter and the DeleteManyModel deletes all the documents that
match your query filter.
Important
When performing a bulkWrite(), the DeleteOneModel and
DeleteManyModel do not delete any documents if there are no matches
to your query filter.
Example
The following example creates a DeleteOneModel to delete
a document where the _id is 1:
DeleteOneModel<Document> deleteDoc = new DeleteOneModel<>(Filters.eq("_id", 1));
For more information about the methods and classes mentioned in this section, see the following API documentation:
Order of Execution
The bulkWrite() method accepts an optional BulkWriteOptions as a
second parameter to specify whether the execution of the bulk operations is
ordered or unordered.
Ordered Execution
By default, the bulkWrite() method executes bulk operations in
order. This means that the bulk operations execute in the order you
added them to the list until an error occurs, if any.
Example
The following example performs these bulk operations:
An operation that inserts a document with a
namevalue of"Zaynab Omar"and anagevalue of37An operation that replaces the document where the
_idis1with a new document that contains thelocationfieldAn operation that updates the document with a
namevalue of"Zaynab Omar"and changes thenameto"Zaynab Hassan"An operation that deletes all documents where the
agevalue is greater than50
List<WriteModel<Document>> bulkOperations = new ArrayList<>(); // Creates instructions to insert a document InsertOneModel<Document> insertDoc = new InsertOneModel<>(new Document("_id", 6) .append("name", "Zaynab Omar") .append("age", 37)); // Creates instructions to replace the first document matched by the query ReplaceOneModel<Document> replaceDoc = new ReplaceOneModel<>(Filters.eq("_id", 1), new Document("name", "Sandy Kane") .append("location", "Helena, MT")); // Creates instructions to update the first document matched by the query UpdateOneModel<Document> updateDoc = new UpdateOneModel<>(Filters.eq("name", "Zaynab Omar"), Updates.set("name", "Zaynab Hassan")); // Creates instructions to delete all documents matched by the query DeleteManyModel<Document> deleteDoc = new DeleteManyModel<>(Filters.gt("age", 50)); bulkOperations.add(insertDoc); bulkOperations.add(replaceDoc); bulkOperations.add(updateDoc); bulkOperations.add(deleteDoc); // Runs a bulk write operation for the specified the insert, replace, update, and delete WriteModels in order collection.bulkWrite(bulkOperations);
After running this example, your collection contains the following document:
{ "_id": 1, "name": "Sandy Kane", "location": "Helena, MT" } { "_id": 8, "name": "Shayla Ray", "age": 20 } { "_id": 6, "name": "Zaynab Hassan", "age": 37 }
Unordered Execution
You can also execute bulk operations in any order by specifying "false"
to the order() method on BulkWriteOptions. This means that
all the write operations execute regardless of errors and if any errors occur
the bulk operation reports them at the end.
Adding to the preceding example, including the following specifies the bulk operations to execute in any order:
BulkWriteOptions options = new BulkWriteOptions().ordered(false); // Runs a bulk write operation for the specified insert, replace, update, and delete WriteModels in any order collection.bulkWrite(bulkOperations, options);
Note
Unordered bulk operations do not guarantee order of execution. The order can differ from the way you list them to optimize the runtime.
In the preceding example, if the bulkWrite() method decided to
perform the insert operation after the update operation, nothing
changes with the update operation because the document does not exist
at that point in time. Your collection then contains the following
documents:
{ "_id": 1, "name": "Sandy Kane", "location": "Helena, MT" } { "_id": 8, "name": "Shayla Ray", "age": 20 } { "_id": 6, "name": "Zaynab Omar", "age": 37 }
For more information about the methods and classes mentioned in this section, see the following API documentation:
Bulk Write Example: Full File
Note
Example Setup
This example connects to an instance of MongoDB by using a
connection URI. To learn more about connecting to your MongoDB
instance, see the Create a MongoClient guide. This example
also uses the movies collection in the sample_mflix database
included in the Atlas sample datasets. You
can load them into your database on the free tier of MongoDB Atlas
by following the Get Started with Atlas Guide.
The following code is a complete, standalone file that performs the following actions:
Creates a list of instances of the
InsertOneModel,UpdateOneModel,DeleteOneModel, andReplaceOneModelclasses.Runs an ordered
bulkWrite()operation that performs the writes specified in the model list.
// Runs bulk write operations on a collection by using the Java driver package org.example; import java.util.Arrays; import org.bson.Document; import com.mongodb.MongoException; import com.mongodb.bulk.BulkWriteResult; import com.mongodb.client.MongoClient; import com.mongodb.client.MongoClients; import com.mongodb.client.MongoCollection; import com.mongodb.client.MongoDatabase; import com.mongodb.client.model.DeleteOneModel; import com.mongodb.client.model.InsertOneModel; import com.mongodb.client.model.ReplaceOneModel; import com.mongodb.client.model.UpdateOneModel; import com.mongodb.client.model.UpdateOptions; public class BulkWrite { public static void main(String[] args) { // Replace the uri string with your MongoDB deployment's connection string String uri = "<connection string uri>"; try (MongoClient mongoClient = MongoClients.create(uri)) { MongoDatabase database = mongoClient.getDatabase("sample_mflix"); MongoCollection<Document> collection = database.getCollection("movies"); // Runs a bulk write operation for the specified insert, update, delete, and replace operations BulkWriteResult result = collection.bulkWrite( Arrays.asList( new InsertOneModel<>(new Document("name", "A Sample Movie")), new InsertOneModel<>(new Document("name", "Another Sample Movie")), new InsertOneModel<>(new Document("name", "Yet Another Sample Movie")), new UpdateOneModel<>(new Document("name", "A Sample Movie"), new Document("$set", new Document("name", "An Old Sample Movie")), new UpdateOptions().upsert(true)), new DeleteOneModel<>(new Document("name", "Yet Another Sample Movie")), new ReplaceOneModel<>(new Document("name", "Yet Another Sample Movie"), new Document("name", "The Other Sample Movie").append("runtime", "42")) )); // Prints the number of inserted, updated, and deleted documents System.out.println("Result statistics:" + "\ninserted: " + result.getInsertedCount() + "\nupdated: " + result.getModifiedCount() + "\ndeleted: " + result.getDeletedCount()); } } }
Result statistics: inserted: 3 updated: 2 deleted: 1
Client Bulk Write
When connecting to a deployment running MongoDB Server 8.0 or later,
you can use the MongoClient.bulkWrite() method to write
to multiple databases and collections in the same cluster. The MongoClient.bulkWrite()
method performs all write operations in a single call.
The MongoClient.bulkWrite() method takes a
list of ClientNamespacedWriteModel instances to represent different write operations.
You can construct instances of the ClientNamespacedWriteModel interface by using
instance methods. For example, an instance of ClientNamespacedInsertOneModel represents an
operation to insert one document, and you can create this model by using
the ClientNamespacedWriteModel.insertOne() method.
Note
Bulk Write Errors
If any of the write operations fail, the driver raises a
ClientBulkWriteException and does not perform any further individual
operations. ClientBulkWriteException includes a BulkWriteError that can
be accessed by using the ClientBulkWriteException.getWriteErrors()
method, which provides details of the individual failure.
The models and their corresponding instance methods are described in the table below.
Model | Instance Method | Description | Parameters |
|---|---|---|---|
|
| Creates a model to insert a document into the |
|
|
| Creates a model to update the first document in the |
You must pass a value for either the |
|
| Creates a model to update all documents in the |
You must pass a value for either the |
|
| Creates a model to replace the first document in the |
|
|
| Creates a model to delete the first document in the |
|
|
| Creates a model to delete all documents in the |
|
The following sections provide examples of how to use the client bulkWrite()
method.
To learn more about the methods and classes mentioned in this section, see the following API documentation:
Insert Example
This example shows how to use the bulkWrite() method to insert
two documents. One document is inserted into the db.people collection, while
the other document is inserted into the db.things collection.
The MongoNamespace instance defines the databases and collections that
each write operation applies to.
MongoNamespace peopleNamespace = new MongoNamespace("db", "people"); MongoNamespace thingsNamespace = new MongoNamespace("db", "things"); List<ClientNamespacedWriteModel> bulkOperations = new ArrayList<>(); bulkOperations.add(ClientNamespacedWriteModel .insertOne( peopleNamespace, new Document("name", "Julia Smith") ) ); bulkOperations.add(ClientNamespacedWriteModel .insertOne( thingsNamespace, new Document("object", "washing machine") ) ); ClientBulkWriteResult result = mongoClient.bulkWrite(bulkOperations);
Update Example
The following example shows how to use the bulkWrite() method to update
existing documents in the db.people and db.things collections:
MongoNamespace peopleNamespace = new MongoNamespace("db", "people"); MongoNamespace thingsNamespace = new MongoNamespace("db", "things"); List<ClientNamespacedWriteModel> bulkOperations = new ArrayList<>(); bulkOperations.add(ClientNamespacedWriteModel.updateOne( peopleNamespace, Filters.eq("name", "Freya Polk"), Updates.inc("age", 1) ) ); bulkOperations.add(ClientNamespacedWriteModel.updateMany( thingsNamespace, Filters.eq("category", "electronic"), Updates.set("manufacturer", "Premium Technologies") ) ); ClientBulkWriteResult result = mongoClient.bulkWrite(bulkOperations);
This example increments the value of the age field by 1 in the
document that has a name value of "Freya Polk" in the people
collection. It also sets the value of the manufacturer field to
"Premium Technologies" in all documents that have a category
value of "electronic" in the things collection.
If multiple documents match the query filter specified in
a ClientNamespacedUpdateOneModel instance, the operation updates the
first result. You can specify a sort order in a ClientUpdateOneOptions
instance to apply an order to matched documents before the driver
performs the update operation, as shown in the following code:
ClientUpdateOneOptions options = ClientUpdateOneOptions .clientUpdateOneOptions() .sort(Sorts.ascending("_id"));
Replace Example
The following example shows how to use the bulkWrite() method to replace
existing documents in the db.people and db.things collections:
MongoNamespace peopleNamespace = new MongoNamespace("db", "people"); MongoNamespace thingsNamespace = new MongoNamespace("db", "things"); List<ClientNamespacedWriteModel> bulkOperations = new ArrayList<>(); bulkOperations.add(ClientNamespacedWriteModel.replaceOne( peopleNamespace, Filters.eq("_id", 1), new Document("name", "Frederic Hilbert") ) ); bulkOperations.add(ClientNamespacedWriteModel.replaceOne( thingsNamespace, Filters.eq("_id", 1), new Document("object", "potato") ) ); ClientBulkWriteResult result = mongoClient.bulkWrite(bulkOperations);
After this example runs successfully, the document that has an _id value of 1
in the people collection is replaced with a new document. The document in
the things collection that has an _id value of 1
is replaced with a new document.
If multiple documents match the query filter specified in
a ClientNamespacedReplaceOneModel instance, the operation replaces the
first result. You can specify a sort order in a ClientReplaceOneOptions
instance to apply an order to matched documents before the driver
performs the replace operation, as shown in the following code:
ClientReplaceOneOptions options = ClientReplaceOneOptions .clientReplaceOneOptions() .sort(Sorts.ascending("_id"));
Bulk Write Options
You can pass an instance of ClientBulkWriteOptions to the bulkWrite()
method to specify options when running the bulk write operations.
Order of Execution Example
By default, the individual operations in a bulk operation are executed in the
order that you specify them until an error occurs, or until they execute
successfully. However, you can pass false to the ordered() method on
the ClientBulkWriteOptions interface to perform write operations in an
unordered way. When using the unordered option, an error-producing operation
does not prevent execution of other write operations in the call to the
bulkWrite() method.
The following code sets the ordered() method on an
instance of ClientBulkWriteOptions and performs a bulk write operation to
insert multiple documents.
MongoNamespace namespace = new MongoNamespace("db", "people"); ClientBulkWriteOptions options = ClientBulkWriteOptions .clientBulkWriteOptions() .ordered(false); List<ClientNamespacedWriteModel> bulkOperations = new ArrayList<>(); bulkOperations.add( ClientNamespacedWriteModel.insertOne( namespace, new Document("_id", 1).append("name", "Rudra Suraj") ) ); // Causes a duplicate key error bulkOperations.add( ClientNamespacedWriteModel.insertOne( namespace, new Document("_id", 1).append("name", "Mario Bianchi") ) ); bulkOperations.add( ClientNamespacedWriteModel.insertOne( namespace, new Document("name", "Wendy Zhang") ) ); ClientBulkWriteResult result = mongoClient.bulkWrite(bulkOperations, options);
Even though the write operation inserting a document with a duplicate key results in an error, the other operations are executed because the write operation is unordered.
Troubleshooting
Bulk Write Exception
If the driver encounters an error during a bulk write operation, the driver
throws a MongoBulkWriteException. A MongoBulkWriteException
contains a writeErrors field consisting of a list of one or more
WriteError objects associated with the same bulk write operation.
Consider a collection that has a schema validation rule where the value of the
quantity field must be an int type. In the following example, the driver
throws a MongoBulkWriteException when you attempt to insert a document with
a quantity field value of "three" and another with a quantity field
value of "ten".
Exception in thread "main" com.mongodb.MongoBulkWriteException: Bulk write operation result had errors at com.mongodb.internal.connection.ProtocolHelper.getBulkWriteException(ProtocolHelper.java:258) ... at BulkWriteMultipleValidationErrorsExample.main(BulkWriteMultipleValidationErrorsExample.java:30) Caused by: com.mongodb.MongoWriteException: WriteError{code=121, message='Document failed validation', details={ operator: "$jsonSchema", schemaRules: { bsonType: "int", description: "must be an integer" }, offendingDocument: {"name":"Apple","quantity":"three"} }} at com.mongodb.internal.connection.WriteResultHelper.createWriteException(WriteResultHelper.java:50) at com.mongodb.internal.connection.ProtocolHelper.getBulkWriteException(ProtocolHelper.java:254) ... 19 more Caused by: com.mongodb.MongoWriteException: WriteError{code=121, message='Document failed validation', details={ operator: "$jsonSchema", schemaRules: { bsonType: "int", description: "must be an integer" }, offendingDocument: {"name":"Banana","quantity":"ten"} }} at com.mongodb.internal.connection.WriteResultHelper.createWriteException(WriteResultHelper.java:50) at com.mongodb.internal.connection.ProtocolHelper.getBulkWriteException(ProtocolHelper.java:254) ... 19 more
To learn more about schema validation, see Schema Validation in the Server Manual Entries section.
Additional Information
API Documentation
To learn more about the methods and classes used to perform bulk write operations in this section, see the following API documentation: