【发布时间】:2017-09-04 13:36:44
【问题描述】:
我有一个函数应该通过“ID”从 mongo 数据库中找到一个问题并返回它,如果它没有找到一个它创建一个然后返回它。它是我的代码中唯一能够在数据库中创建新问题实体的函数。这里是: (顺便说一句,我正在为 nodeJs 使用官方的 MongoDb 驱动程序)
function getQuestionEntity(questionID, cb){
const questions = db.collection('questions')
questions.findOneAndUpdate(
{ID: questionID},
{$setOnInsert:
{
ID: questionID,
rating: 1.5,
options: 4,
answeredRight: 0,
answeredWrong: 0
}
},
{
returnOriginal: false,
upsert: true
},
(err, r)=>{
if(err){throw new Error(err)}
cb(r.value)
}
)
}
我读到 findOneAndUpdate 是一个原子操作,这意味着即使我异步循环这个函数到时间结束,我仍然不会在数据库中获得两个具有相同“ID”字段的问题实体,但是这正是发生的事情。
我的代码有什么问题吗?我的假设错了吗?
【问题讨论】:
-
更新操作是原子的,但 upsert 不是。见here。所以需要给
ID添加唯一索引,然后在出现重复键错误时进行处理。