Beginning with MongoDB 2.4, it's no longer necessary to rely on a unique index (or any other workaround) for atomic findOrCreate
like operations.
This is thanks to the $setOnInsert
operator new to 2.4, which allows you to specify updates which should only happen when inserting documents.
This, combined with the upsert
option, means you can use findAndModify
to achieve an atomic findOrCreate
-like operation.
db.collection.findAndModify({
query: { _id: "some potentially existing id" },
update: {
$setOnInsert: { foo: "bar" }
},
new: true, // return new doc if one is upserted
upsert: true // insert the document if it does not exist
})
As $setOnInsert
only affects documents being inserted, if an existing document is found, no modification will occur. If no document exists, it will upsert one with the specified _id, then perform the insert only set. In both cases, the document is returned.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…