Insert or Update in a Single Operation
On this page
Overview
In this guide, you can learn how to perform an upsert with the MongoDB Kotlin driver.
Applications use insert and update operations to store and modify data.
Sometimes, you need to choose between an insert and update depending on
whether the document exists. MongoDB simplifies this decision for us
with an upsert
option.
An upsert
:
Updates documents that match your query filter
Inserts a document if there are no matches to your query filter
Specify an Upsert
To specify an upsert with the updateOne()
or updateMany()
methods, pass true
to UpdateOptions.upsert()
.
To specify an upsert with the replaceOne()
method, pass true
to
ReplaceOptions.upsert()
.
In the following example, a paint store sells eight different
colors of paint. The store had their annual online sale. Their
paint_inventory
collection now shows the following documents:
{ "_id": { "$oid": "606b4cfbcd83be7518b958da" }, "color": "red", "qty": 5 } { "_id": { "$oid": "606b4cfbcd83be7518b958db" }, "color": "purple", "qty": 8 } { "_id": { "$oid": "606b4cfbcd83be7518b958dc" }, "color": "blue", "qty": 0 } { "_id": { "$oid": "606b4cfbcd83be7518b958dd" }, "color": "white", "qty": 0 } { "_id": { "$oid": "606b4cfbcd83be7518b958de" }, "color": "yellow", "qty": 6 } { "_id": { "$oid": "606b4cfbcd83be7518b958df" }, "color": "pink", "qty": 0 } { "_id": { "$oid": "606b4cfbcd83be7518b958e0" }, "color": "green", "qty": 0 } { "_id": { "$oid": "606b4cfbcd83be7518b958e1" }, "color": "black", "qty": 8 }
This data is modeled with the following Kotlin data class:
data class PaintOrder( val id: ObjectId = ObjectId(), val qty: Int, val color: String )
The store received a fresh shipment and needs to update their inventory. The first item in the shipment is ten cans of orange paint.
To update the inventory, query the paint_inventory
collection
where the color
is "orange"
, specify an update to increment
the
qty
field by 10
, and specify true
to
UpdateOptions.upsert()
:
val filter = Filters.eq(PaintOrder::color.name, "orange") val update = Updates.inc(PaintOrder::qty.name, 10) val options = UpdateOptions().upsert(true) val results = collection.updateOne(filter, update, options) println(results)
AcknowledgedUpdateResult{ matchedCount=0, modifiedCount=0, upsertedId=BsonObjectId{ value=606b4cfc1601f9443b5d6978 }}
This AcknowledgedUpdateResult
tells us:
Zero documents matched our query filter
Zero documents in our collection got modified
A document with an
_id
of606b4cfc1601f9443b5d6978
got upserted
The following shows the documents in the paint_inventory
collection:
{ "_id": { "$oid": "606b4cfbcd83be7518b958da" }, "color": "red", "qty": 5 } { "_id": { "$oid": "606b4cfbcd83be7518b958db" }, "color": "purple", "qty": 8 } { "_id": { "$oid": "606b4cfbcd83be7518b958dc" }, "color": "blue", "qty": 0 } { "_id": { "$oid": "606b4cfbcd83be7518b958dd" }, "color": "white", "qty": 0 } { "_id": { "$oid": "606b4cfbcd83be7518b958de" }, "color": "yellow", "qty": 6 } { "_id": { "$oid": "606b4cfbcd83be7518b958df" }, "color": "pink", "qty": 0 } { "_id": { "$oid": "606b4cfbcd83be7518b958e0" }, "color": "green", "qty": 0 } { "_id": { "$oid": "606b4cfbcd83be7518b958e1" }, "color": "black", "qty": 8 } { "_id": { "$oid": "606b4cfc1601f9443b5d6978" }, "color": "orange", "qty": 10 }]
Note
Not including UpdateOptions
results in no change to the collection.
val filter = Filters.eq(PaintOrder::color.name, "orange") val update = Updates.inc(PaintOrder::qty.name, 10) val results = collection.updateOne(filter, update) println(results)
AcknowledgedUpdateResult{ matchedCount=0, modifiedCount=0, upsertedId=null }
For more information about the methods and classes mentioned in this section, see the following API Documentation: