Answers:
从MongoDB 2.4开始,不再需要findOrCreate
像原子操作那样依赖唯一索引(或任何其他解决方法)。
这要归功于2.4新增的$setOnInsert
运算符,该运算符使您可以指定仅在插入文档时进行的更新。
结合使用该upsert
选项,意味着您可以findAndModify
用来实现findOrCreate
类似原子的操作。
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
})
因为$setOnInsert
仅影响插入的文档,所以如果找到现有文档,则不会进行任何修改。如果不存在任何文档,它将使用指定的_id向上插入一个文档,然后执行仅插入集。在两种情况下,都将返回文档。
db.collection.findAndModify({query: {_id: "some potentially existing id"}, update: {$setOnInsert: {foo: "bar"}}, new: true, upsert: true})
)插入(UPSERT)编一个文件,你应该考虑使用db.collection.updateOne({_id: "some potentially existing id"}, {$setOnInsert: {foo: "bar"}}, {upsert: true})
。如果文档已{"acknowledged": true, "matchedCount": 0, "modifiedCount": 0, "upsertedId": ObjectId("for newly inserted one")}
插入,{"acknowledged": true, "matchedCount": 1, "modifiedCount": 0}
则返回该文档。
findOneAndUpdate
,findOneAndReplace
或findOneAndDelete
采用最新的驱动程序(> 2版),您将使用findOneAndUpdate作为findAndModify
被废弃。这种新方法需要3个参数的filter
,该update
对象(其中包含您的默认属性,应插入一个新的对象),并options
在那里你必须指定更新插入操作。
使用promise语法,它看起来像这样:
const result = await collection.findOneAndUpdate(
{ _id: new ObjectId(id) },
{
$setOnInsert: { foo: "bar" },
},
{
returnOriginal: false,
upsert: true,
}
);
const newOrUpdatedDocument = result.value;
它有点脏,但是您可以将其插入。
确保键上具有唯一索引(如果使用_id没关系,那么它已经是唯一的)。
这样,如果元素已经存在,它将返回一个您可以捕获的异常。
如果不存在,将插入新文档。
更新: MongoDB文档中对此技术的详细说明
collection.findAndModify({_id:'theId'}, <your sort opts>, {$setOnInsert:{foo: 'bar'}}, {new:true, upsert:true}, callback)
。请参阅文档