Bulk Write Operations
On this page
Overview
This guide shows you how to use the Kotlin Sync driver to perform a bulk write operation that makes multiple changes to your data in a single database call.
Consider a situation that requires you to insert documents, update documents, and delete documents for the same task. If you use the individual write methods to perform each type of operation, each write accesses the database separately. You can use a bulk write operation to optimize the number of calls your application makes to the server.
Sample Data
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 with Atlas guide.
The documents in this collection are modeled by the following Kotlin data class:
data class Restaurant( val name: String, val borough: String, val cuisine: String )
Define the Write Operations
For each write operation you want to perform, create a corresponding
instance of one of the following operation classes that inherit from the
generic WriteModel
class:
InsertOneModel
UpdateOneModel
UpdateManyModel
ReplaceOneModel
DeleteOneModel
DeleteManyModel
Then, pass a list of these instances to the bulkWrite()
method.
The following sections show how to create and use instances of the
preceding classes. The Perform the Bulk Operation section
demonstrates how to pass a list of models to the bulkWrite()
method
to perform the bulk operation.
Insert Operations
To perform an insert operation, create an InsertOneModel
instance and specify
the document you want to insert.
The following example creates an instance of InsertOneModel
:
val blueMoon = InsertOneModel(Restaurant("Blue Moon Grill", "Brooklyn", "American"))
To insert multiple documents, create an instance of InsertOneModel
for each document.
Important
When performing a bulk operation, the InsertOneModel
cannot
insert a document with an _id
that already exists in the
collection. In this situation, the driver throws a
MongoBulkWriteException
.
Update Operations
To update a document, create an instance of UpdateOneModel
and pass
the following arguments:
A query filter that specifies the criteria used to match documents in your collection
The update operation you want to perform. For more information about update operations, see the Field Update Operators guide in the MongoDB Server manual.
An UpdateOneModel
instance specifies an update for the first
document that matches your query filter.
The following example creates an instance of UpdateOneModel
:
val updateOneFilter = Filters.eq(Restaurant::name.name, "White Horse Tavern") val updateOneDoc = Updates.set(Restaurant::borough.name, "Queens") val tavernUpdate = UpdateOneModel<Restaurant>(updateOneFilter, updateOneDoc)
To update multiple documents, create an instance of UpdateManyModel
and pass
the same arguments as for UpdateOneModel
. The UpdateManyModel
class specifies updates for all documents that match your query
filter.
The following example creates an instance of UpdateManyModel
:
val updateManyFilter = Filters.eq(Restaurant::name.name, "Wendy's") val updateManyDoc = Updates.set(Restaurant::cuisine.name, "Fast food") val wendysUpdate = UpdateManyModel<Restaurant>(updateManyFilter, updateManyDoc)
Replace Operations
A replace operation removes all fields and values of a specified document and
replaces them with new fields and values that you specify. To perform a
replace operation, create an instance of ReplaceOneModel
and pass a
query filter and the fields and values you want to replace the matching
document with.
The following example creates an instance of ReplaceOneModel
:
val replaceFilter = Filters.eq(Restaurant::name.name, "Cooper Town Diner") val replaceDoc = Restaurant("Smith Town Diner", "Brooklyn", "American") val replacement = ReplaceOneModel(replaceFilter, replaceDoc)
To replace multiple documents, you must create an instance of
ReplaceOneModel
for each document.
Delete Operations
To delete a document, create an instance of DeleteOneModel
and pass a
query filter specifying the document you want to delete. A
DeleteOneModel
instance provides instructions to delete
only the first document that matches your query filter.
The following example creates an instance of DeleteOneModel
:
val deleteOne = DeleteOneModel<Restaurant>(Filters.eq( Restaurant::name.name, "Morris Park Bake Shop" ))
To delete multiple documents, create an instance of DeleteManyModel
and pass a
query filter specifying the document you want to delete. An instance of
DeleteManyModel
provides instructions to remove all documents that
match your query filter.
The following example creates an instance of DeleteManyModel
:
val deleteMany = DeleteManyModel<Restaurant>(Filters.eq( Restaurant::cuisine.name, "Experimental" ))
Perform the Bulk Operation
After you define a model 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
specified by the list of models.
The following example performs multiple write operations by using the
bulkWrite()
method:
val insertOneMdl = InsertOneModel(Restaurant("Red's Pizza", "Brooklyn", "Pizzeria")) val updateOneMdl = UpdateOneModel<Restaurant>( Filters.eq(Restaurant::name.name, "Moonlit Tavern"), Updates.set(Restaurant::borough.name, "Queens") ) val deleteManyMdl = DeleteManyModel<Restaurant>( Filters.eq(Restaurant::name.name, "Crepe") ) val bulkResult = collection.bulkWrite( listOf(insertOneMdl, updateOneMdl, deleteManyMdl) ) println(bulkResult)
AcknowledgedBulkWriteResult{insertedCount=1, matchedCount=5, removedCount=3, modifiedCount=2, upserts=[], inserts=[BulkWriteInsert{index=0, id=BsonObjectId{value=...}}]}
If any of the write operations fail, the Kotlin Sync driver raises a
BulkWriteError
and does not perform any further operations.
BulkWriteError
provides a details
item that includes the
operation that failed, and details about the exception.
Note
When the driver runs a bulk operation, it uses the write concern of the target collection. The driver reports all write concern errors after attempting all operations, regardless of execution order.
Customize Bulk Write Operation
The bulkWrite()
method optionally accepts a parameter which
specifies options you can use to configure the bulk write
operation. If you don't specify any options, the driver performs the
bulk operation with default settings.
The following table describes the setter methods that you can use to
configure a BulkWriteOptions
instance:
Property | Description |
---|---|
ordered() | If true , the driver performs the write operations in the order
provided. If an error occurs, the remaining operations are not
attempted.If false , the driver performs the operations in an
arbitrary order and attempts to perform all operations.Defaults to true . |
bypassDocumentValidation() | Specifies whether the update operation bypasses document validation. This lets you
update 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. Defaults to false . |
comment() | Sets a comment to attach to the operation. |
let() | Provides a map of parameter names and values to set top-level
variables for the operation. Values must be constant or closed
expressions that don't reference document fields. |
The following code creates options and uses the ordered(false)
option to
specify an unordered bulk write. Then, the example uses the
bulkWrite()
method to perform a bulk operation:
val opts = BulkWriteOptions().ordered(false) collection.bulkWrite(bulkOperations, opts)
If any of the write operations in an unordered bulk write fail, the Kotlin Sync driver reports the errors only after attempting all operations.
Note
Unordered bulk operations do not guarantee an order of execution. The order can differ from the way you list them to optimize the runtime.
Return Value
The bulkWrite()
method returns a BulkWriteResult
object. You can
access the following information from a BulkWriteResult
instance:
Property | Description |
---|---|
wasAcknowledged() | Indicates if the server acknowledged the write operation. |
getDeletedCount() | The number of documents deleted, if any. |
getInsertedCount() | The number of documents inserted, if any. |
getInserts() | The list of inserted documents, if any. |
getMatchedCount() | The number of documents matched for an update, if applicable. |
getModifiedCount() | The number of documents modified, if any. |
getUpserts() | The list of upserted documents, if any. |
Additional Information
To learn how to perform individual write operations, see the following guides:
API Documentation
To learn more about any of the methods or types discussed in this guide, see the following API Documentation: