Docs Menu
Docs Home
/ / /
Java Reactive Streams Driver
/

Bulk Write Operations

On this page

  • Overview
  • Sample Data
  • Collection Bulk Write
  • Insert Operations
  • Update Operations
  • Replace Operations
  • Delete Operations
  • Perform the Bulk Operation
  • Customize Bulk Write
  • Client Bulk Write
  • Insert Operations
  • Replace Operations
  • Perform the Bulk Operation
  • Customize Bulk Write
  • Additional Information
  • API Documentation

In this guide, you can learn how to perform multiple write operations in a single database call by using bulk write operations.

Consider a scenario in which you want to insert a document, update multiple other documents, then delete a document. If you use individual methods, each operation requires its own database call.

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.

The examples in this guide use the sample_restaurants.restaurants collection from the Atlas sample datasets. To learn how to create a free MongoDB Atlas cluster and load the sample datasets, see the Get Started tutorial.

Important

Project Reactor Library

This guide uses the Project Reactor library to consume Publisher instances returned by the Java Reactive Streams driver methods. To learn more about the Project Reactor library and how to use it, see Getting Started in the Reactor documentation. To learn more about how we use Project Reactor library methods in this guide, see the Write Data to MongoDB guide.

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.

For each write operation you want to perform, create an instance of one of the following classes that inherit from WriteModel:

  • InsertOneModel

  • UpdateOneModel

  • UpdateManyModel

  • ReplaceOneModel

  • DeleteOneModel

  • DeleteManyModel

The following sections show how to create and use instances of the preceding classes.

To perform an insert operation, create an instance of InsertOneModel and pass in the document you want to insert.

The following example creates an instance of InsertOneModel:

InsertOneModel<Document> operation = new InsertOneModel<>(
new Document("name", "Mongo's Deli")
.append("cuisine", "Sandwiches"));

To insert multiple documents, create an instance of InsertOneModel for each document.

To update a document, create an instance of UpdateOneModel and pass in the following arguments:

  • Query filter that specifies the criteria used to match documents in your collection.

  • Update operation you want to perform. For more information about update operations, see the Field Update Operators guide in the MongoDB Server manual.

The following example creates an instance of UpdateOneModel:

UpdateOneModel<Document> operation = new UpdateOneModel<>(
eq("name", "Mongo's Deli"),
set("cuisine", "Sandwiches and Salads"));

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 driver performs the update operation, as shown in the following code:

UpdateOptions options = UpdateOptions.sort(Sorts.ascending("_id"));

To update multiple documents, create an instance of UpdateManyModel and pass in the same arguments. UpdateManyModel updates all documents that match your query filter.

The following example creates an instance of UpdateManyModel:

UpdateManyModel<Document> operation = new UpdateManyModel<>(
eq("name", "Mongo's Deli"),
set("cuisine", "Sandwiches and Salads"));

A replace operation removes all fields and values of a specified document, aside from the _id field, and replaces them with new ones. To perform a replace operation, create an instance of ReplaceOneModel and pass in a query filter and the fields and values you want to store in the matching document.

The following example creates an instance of ReplaceOneModel:

ReplaceOneModel<Document> operation = new ReplaceOneModel<>(
eq("name", "Original Pizza"),
new Document("name", "Mongo's Pizza")
.append("borough", "Manhattan"));

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 driver performs the replace operation, as shown in the following code:

ReplaceOptions options = ReplaceOptions.sort(Sorts.ascending("_id"));

Tip

Replace Multiple Documents

To replace multiple documents, create an instance of ReplaceOneModel for each document.

To delete a document, create an instance of DeleteOneModel and pass in a query filter specifying the document you want to delete. DeleteOneModel removes only the first document that matches your query filter.

The following example creates an instance of DeleteOneModel:

DeleteOneModel<Document> operation = new DeleteOneModel<>(
eq("restaurant_id", "5678"));

To delete multiple documents, create an instance of DeleteManyModel and pass in a query filter specifying the documents you want to delete. DeleteManyModel removes all documents that match your query filter.

The following example creates an instance of DeleteManyModel:

DeleteManyModel<Document> operation = new DeleteManyModel<>(
eq("name", "Mongo's Deli"));

After you define a WriteModel instance for each operation you want to perform, pass a list of these instances to the bulkWrite() method. By default, the method runs the operations in the order they're defined in the list.

The following example performs multiple write operations by using the bulkWrite() method:

Publisher<BulkWriteResult> bulkWritePublisher = restaurants.bulkWrite(
Arrays.asList(new InsertOneModel<>(
new Document("name", "Mongo's Deli")
.append("cuisine", "Sandwiches")
.append("borough", "Manhattan")
.append("restaurant_id", "1234")),
new InsertOneModel<>(new Document("name", "Mongo's Deli")
.append("cuisine", "Sandwiches")
.append("borough", "Brooklyn")
.append("restaurant_id", "5678")),
new UpdateManyModel<>(eq("name", "Mongo's Deli"),
set("cuisine", "Sandwiches and Salads")),
new DeleteOneModel<>(eq("restaurant_id", "1234"))));
BulkWriteResult bulkResult = Mono.from(bulkWritePublisher).block();
System.out.println(bulkResult.toString());
AcknowledgedBulkWriteResult{insertedCount=2, matchedCount=2, removedCount=1, modifiedCount=2, upserts=[], inserts=[BulkWriteInsert{index=0, id=BsonObjectId{value=66a7e0a6c08025218b657208}}, BulkWriteInsert{index=1, id=BsonObjectId{value=66a7e0a6c08025218b657209}}]}

If any of the write operations fail, the Java Reactive Streams driver signals a MongoBulkWriteException and does not perform any further individual operations. MongoBulkWriteException includes a BulkWriteError that can be accessed by using the MongoBulkWriteException.getWriteErrors() method, which provides details of the individual failure.

Note

When the Java Reactive Streams driver runs a bulk operation, it uses the writeConcern of the collection on which the operation is running. The driver reports all write concern errors after attempting all operations, regardless of execution order.

The BulkWriteOptions class contains methods that modify the behavior of the bulkWrite() method. To use the BulkWriteOptions class, construct a new instance of the class, then call one or more of its methods to modify the write operation. You can chain these method calls together. To modify the behavior of the write operation, pass the class instance as the last argument to the bulkWrite() method.

You can use the following methods in the BulkWriteOptions class to modify a write method. All methods are optional.

Method
Description

bypassDocumentValidation(Boolean bypassDocumentValidation)

Specifies whether the bulk write operation bypasses document validation. This lets you perform write operations on documents that don't meet the schema validation requirements, if any exist. For more information about schema validation, see Schema Validation in the MongoDB Server manual.

comment(Bson comment)

Attaches a Bson comment to the operation. For more information, see the insert command fields guide in the MongoDB Server manual.

comment(String comment)

Attaches a String comment to the operation. For more information, see the insert command fields guide in the MongoDB Server manual.

let(Bson variables)

Specifies a map of parameter names and values. Values must be constant or closed expressions that don't reference document fields. For more information, see the let statement in the MongoDB Server manual.

ordered(Boolean ordered)

If set to True, the driver performs the individual operations in the order provided. If an individual operation fails, the driver will not execute any subsequent individual operations.
Defaults to True.

The following example calls the bulkWrite() method from the preceding example but sets the ordered option to False:

Publisher<BulkWriteResult> bulkWritePublisher = restaurants.bulkWrite(
Arrays.asList(new InsertOneModel<>(
new Document("name", "Mongo's Deli")
.append("cuisine", "Sandwiches")
.append("borough", "Manhattan")
.append("restaurant_id", "1234")),
new InsertOneModel<>(new Document("name", "Mongo's Deli")
.append("cuisine", "Sandwiches")
.append("borough", "Brooklyn")
.append("restaurant_id", "5678")),
new UpdateManyModel<>(eq("name", "Mongo's Deli"),
set("cuisine", "Sandwiches and Salads")),
new DeleteOneModel<>(eq("restaurant_id", "1234"))),
new BulkWriteOptions().ordered(false));
BulkWriteResult bulkResult = Mono.from(bulkWritePublisher).block();
System.out.println(bulkResult.toString());
AcknowledgedBulkWriteResult{insertedCount=2, matchedCount=2, removedCount=1, modifiedCount=2, upserts=[], inserts=[BulkWriteInsert{index=0, id=BsonObjectId{value=66a7e03cce430c5854b6caf9}}, BulkWriteInsert{index=1, id=BsonObjectId{value=66a7e03cce430c5854b6cafa}}]}

If any of the write operations in an unordered bulk write fail, the Java Reactive Streams driver reports the errors only after attempting all operations.

Note

Unordered bulk operations do not guarantee order of execution. The order can differ from the way you list them to optimize the runtime.

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.

The models and their corresponding instance methods are described in the table below.

Model
Instance Method
Description
Parameters

ClientNamespacedInsertOneModel

insertOne()

Creates a model to insert a document into the namespace.

namespace: Database and collection to write to

document: Document to insert

ClientNamespacedUpdateOneModel

updateOne()

Creates a model to update the first document in the namespace that matches filter.

namespace: Database and collection to write to

filter: Filter that selects which document to update

update: Update to apply to matching document

updatePipeline: Update pipeline to apply to matching document

options: (optional) Options to apply when updating document

You must pass a value for either the update or updatePipeline parameter.

ClientNamespacedUpdateManyModel

updateMany()

Creates a model to update all documents in the namespace that match filter.

namespace: Database and collection to write to

filter: Filter that selects which documents to update

update: Update to apply to matching documents

updatePipeline: Update pipeline to apply to matching documents

options: (optional) Options to apply when updating documents

You must pass a value for either the update or updatePipeline parameter.

ClientNamespacedReplaceOneModel

replaceOne()

Creates a model to replace the first document in the namespace that matches filter.

namespace: Database and collection to write to

filter: Filter that selects which document to replace

replacement: Replacement document

options: (optional) Options to apply when replacing documents

ClientNamespacedDeleteOneModel

deleteOne()

Creates a model to delete the first document in the namespace that matches filter.

namespace: Database and collection to write to

filter: Filter that selects which document to delete

option: (optional) Options to apply when deleting document

ClientNamespacedDeleteManyModel

deleteMany()

Creates a model to delete all documents in the namespace that match filter.

namespace: Database and collection to write to

filter: Filter that selects which documents to delete

option: (optional) Options to apply when deleting documents

The following sections provide some examples of how to create models and use the client bulkWrite() method.

This example shows how to create models that contain instructions to insert two documents. One document is inserted into the db.people collection, and the other document is inserted into the db.things collection. The MongoNamespace instance defines the target database and collection that each write operation applies to.

ClientNamespacedInsertOneModel personToInsert = ClientNamespacedWriteModel
.insertOne(
new MongoNamespace("db", "people"),
new Document("name", "Julia Smith")
);
ClientNamespacedInsertOneModel thingToInsert = ClientNamespacedWriteModel
.insertOne(
new MongoNamespace("db", "things"),
new Document("object", "washing machine")
);

The following example shows how to create models to replace existing documents in the db.people and db.things collections:

ClientNamespacedReplaceOneModel personReplacement = ClientNamespacedWriteModel
.replaceOne(
new MongoNamespace("db", "people"),
Filters.eq("_id", 1),
new Document("name", "Frederic Hilbert")
);
ClientNamespacedReplaceOneModel thingReplacement = ClientNamespacedWriteModel
.replaceOne(
new MongoNamespace("db", "things"),
Filters.eq("_id", 1),
new Document("object", "potato")
);

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.

After you define a ClientNamespacedWriteModel instance for each operation you want to perform, pass a list of these instances to the client bulkWrite() method. By default, the method runs the operations in the order they're specified.

The following example performs multiple write operations by using the bulkWrite() method:

MongoNamespace peopleNamespace = new MongoNamespace("db", "people");
MongoNamespace thingsNamespace = new MongoNamespace("db", "things");
List<ClientNamespacedWriteModel> bulkOperations = Arrays.asList(
ClientNamespacedWriteModel
.insertOne(
peopleNamespace,
new Document("name", "Corey Kopper")
),
ClientNamespacedWriteModel
.replaceOne(
thingsNamespace,
Filters.eq("_id", 1),
new Document("object", "potato")
)
);
Publisher<ClientBulkWriteResult> bulkWritePublisher = mongoClient
.bulkWrite(bulkOperations);
ClientBulkWriteResult clientBulkResult = Mono
.from(bulkWritePublisher)
.block();
System.out.println(clientBulkResult.toString());
AcknowledgedSummaryClientBulkWriteResult{insertedCount=1, matchedCount=1, ...}

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.

You can pass an instance of ClientBulkWriteOptions to the bulkWrite() method to customize how the driver performs the bulk write operation.

By default, the driver runs the individual operations in a bulk operation in the order that you specify them until an error occurs, or until the operation completes successfully.

However, you can pass false to the ordered() method when creating a ClientBulkWriteOptions instance to direct the driver to perform write operations in an unordered way. When using the unordered option, an error-producing operation does not prevent the driver from running other write operations in the bulk write operation.

The following code sets the ordered option to false in 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 = Arrays.asList(
ClientNamespacedWriteModel.insertOne(
namespace,
new Document("_id", 1).append("name", "Rudra Suraj")
),
// Causes a duplicate key error
ClientNamespacedWriteModel.insertOne(
namespace,
new Document("_id", 1).append("name", "Mario Bianchi")
),
ClientNamespacedWriteModel.insertOne(
namespace,
new Document("name", "Wendy Zhang")
)
);
Publisher<ClientBulkWriteResult> bulkWritePublisher = mongoClient
.bulkWrite(bulkOperations, options);

Even though the write operation inserting a document with a duplicate key results in an error, the other operations are performed because the write operation is unordered.

To learn how to perform individual write operations, see the following guides:

To learn more about any of the methods or types discussed in this guide, see the following API documentation:

Back

Delete