Bulk.find.upsert()
On this page
Tip
Starting in version 3.2, MongoDB also provides the
db.collection.bulkWrite()
method for performing bulk
write operations.
Description
Bulk.find.upsert()
Sets the upsert option to true for an update or a replacement operation and has the following syntax:
Bulk.find(<query>).upsert().update(<update>); Bulk.find(<query>).upsert().updateOne(<update>); Bulk.find(<query>).upsert().replaceOne(<replacement>); With the
upsert
option set totrue
, if no matching documents exist for theBulk.find()
condition, then the update or the replacement operation performs an insert. If a matching document does exist, then the update or replacement operation performs the specified update or replacement.Use
Bulk.find.upsert()
with the following write operations:
Behavior
The following describe the insert behavior of various write operations
when used in conjunction with Bulk.find.upsert()
.
Insert for Bulk.find.replaceOne()
The Bulk.find.replaceOne()
method accepts, as its parameter,
a replacement document that only contains field and value pairs:
var bulk = db.items.initializeUnorderedBulkOp(); bulk.find( { item: "abc123" } ).upsert().replaceOne( { item: "abc123", status: "P", points: 100, } ); bulk.execute();
If the replacement operation with the Bulk.find.upsert()
option performs an insert, the inserted document is the replacement
document. If neither the replacement document nor the query document
specifies an _id
field, MongoDB adds the _id
field:
{ "_id" : ObjectId("52ded3b398ca567f5c97ac9e"), "item" : "abc123", "status" : "P", "points" : 100 }
Insert for Bulk.find.updateOne()
The Bulk.find.updateOne()
method accepts as its
parameter either:
a replacement document that contains only field and value pairs (same as
Bulk.find.replaceOne()
),an update document that contains only update operator expressions, or
an aggregation pipeline (Starting in MongoDB 4.2).
Field and Value Pairs
If the parameter is a replacement document that contains only field and value pairs:
var bulk = db.items.initializeUnorderedBulkOp(); bulk.find( { status: "P" } ).upsert().updateOne( { item: "TBD", points: 0, inStock: true, status: "I" } ); bulk.execute();
Then, if the update operation with the Bulk.find.upsert()
option performs an insert, the inserted document is the replacement
document. If neither the replacement document nor the query document
specifies an _id
field, MongoDB adds the _id
field:
{ "_id" : ObjectId("52ded5a898ca567f5c97ac9f"), "item" : "TBD", "points" : 0, "inStock" : true, "status" : "I" }
Update Operator Expressions
If the parameter is an update document that contains only update operator expressions:
var bulk = db.items.initializeUnorderedBulkOp(); bulk.find( { status: "P", item: null } ).upsert().updateOne( { $setOnInsert: { qty: 0, inStock: true }, $set: { points: 0 } } ); bulk.execute();
Then, if the update operation with the Bulk.find.upsert()
option performs an insert, the update operation inserts a document with
field and values from the query document of the
Bulk.find()
method and then applies the specified updates from
the update document. If neither the update document nor the query document
specifies an _id
field, MongoDB adds the _id
field:
{ "_id" : ObjectId("5e28d1a1500153bc2872dadd"), "item" : null, "status" : "P", "inStock" : true, "points" : 0, "qty" : 0 }
Aggregation Pipeline
Starting in version 4.2, update methods can accept an aggregation pipeline. For example, the following uses:
the
$replaceRoot
stage which can provide somewhat similar behavior to a$setOnInsert
update operator expression,the
$set
stage which can provide similar behavior to the$set
update operator expression,the aggregation variable
NOW
, which resolves to the current datetime and can provide similar behavior to a$currentDate
update operator expression.
var bulk = db.items.initializeUnorderedBulkOp(); bulk.find( { item: "Not Found", status: "P" } ).upsert().updateOne( [ { $replaceRoot: { newRoot: { $mergeObjects: [ { qty: 0, inStock: true }, "$$ROOT" ] } } }, { $set: { points: 0, lastModified: "$$NOW" } } ] ); bulk.execute();
Then, if the update operation with the Bulk.find.upsert()
option performs an insert, the update operation inserts a document with
field and values from the query document of the Bulk.find()
method and then applies the specified aggregation pipeline. If neither
the update document nor the query document specifies an _id
field,
MongoDB adds the _id
field:
{ "_id" : ObjectId("5e28cf1e500153bc2872d49f"), "qty" : 0, "inStock" : true, "item" : "Not Found", "status" : "P", "points" : 0, "lastModified" : ISODate("2020-01-22T22:39:26.789Z") }
Insert for Bulk.find.update()
When using upsert()
with the multiple document
update method Bulk.find.update()
, if no documents match the
query condition, the update operation inserts a single document.
The Bulk.find.update()
method accepts as its parameter either:
an update document that contains only update operator expressions, or
an aggregation pipeline (Starting in MongoDB 4.2).
Update Operator Expressions
If the parameter is an update document that contains only update operator expressions:
var bulk = db.items.initializeUnorderedBulkOp(); bulk.find( { status: "P" } ).upsert().update( { $setOnInsert: { qty: 0, inStock: true }, $set: { status: "I", points: "0" } } ); bulk.execute();
Then, if the update operation with the Bulk.find.upsert()
option performs an insert, the update operation inserts a single
document with the fields and values from the query document of
the Bulk.find()
method and then applies the specified update
from the update document. If neither the update document
nor the query document specifies an _id
field, MongoDB adds
the _id
field:
{ "_id": ObjectId("52ded81a98ca567f5c97aca1"), "status": "I", "qty": 0, "inStock": true, "points": "0" }
Aggregation Pipeline
Starting in version 4.2, update methods can accept an aggregation pipeline. For example, the following uses:
the
$replaceRoot
stage which can provide somewhat similar behavior to a$setOnInsert
update operator expression,the
$set
stage which can provide similar behavior to the$set
update operator expression,the aggregation variable
NOW
, which resolves to the current datetime and can provide similar behavior to the$currentDate
update operator expression. The value ofNOW
remains the same throughout the pipeline. To access aggregation variables, prefix the variable with double dollar signs$$
and enclose in quotes.
var bulk = db.items.initializeUnorderedBulkOp(); bulk.find( { item: "New Item", status: "P" } ).upsert().update( [ { $replaceRoot: { newRoot: { $mergeObjects: [ { qty: 0, inStock: true }, "$$ROOT" ] } } }, { $set: { points: 0, lastModified: "$$NOW" } } ] ); bulk.execute();
Then, if the update operation with the Bulk.find.upsert()
option performs an insert, the update operation inserts a single
document with the fields and values from the query document of the
Bulk.find()
method and then applies the aggregation pipeline.
If neither the update document nor the query document specifies an
_id
field, MongoDB adds the _id
field:
{ "_id" : ObjectId("5e2920a5b4c550aad59d18a1"), "qty" : 0, "inStock" : true, "item" : "New Item", "status" : "P", "points" : 0, "lastModified" : ISODate("2020-01-23T04:27:17.780Z") }