如何在mongo和javascript中控制一个集合字段中的多个更新?

时间:2017-10-27 17:52:23

标签: javascript node.js mongodb mongoose

假设我有一份文件

{
  maxCountAllowed:100,
  currentCount:99
}

我有一个API,用户调用它来增加currentCount,如果它还不是100 ..

if(document.currentCount < document.maxCountAllowed){
    document.currentCount ++;
    document.save();
}else{
    console.log("sorry maximum count reached");
}

假设有2个或更多用户同时调用API ..他们都会发现currentCount仍然是99,因此函数将继续执行,并且它们都将递增currentCount是101或更多...我怎么能防止这样的事情? 即使它们都是100,我仍然只希望其中一个能够更新而另一个得到错误信息。

3 个答案:

答案 0 :(得分:3)

Mongo提供文档级原子性,如下所述:https://docs.mongodb.com/v3.4/tutorial/update-documents/#behavior这意味着如果对象上有两个并发更新操作,那么它们将连续执行。

此外,更新操作支持$ inc运营商:https://docs.mongodb.com/manual/reference/operator/update/inc/#up._S_inc

最后一部分是$ where where运算符:https://docs.mongodb.com/manual/reference/operator/query/where/#examples请记住,它不像查询常量那样高效。

所以你只能更新符合要求的文件:

db.products.update(
  { $where : "this.currentCount < this.maxCountAllowed" },
  { $inc: { currentCount: 1 } }
);

然后检查操作结果以确定是否有任何更新。

答案 1 :(得分:1)

您可以在数据库上执行此操作作为具有其他查询条件的更新。首先,您必须获取文档以了解限制。然后让我们假设您的文档的_id等于1,因此您可以执行此类更新:

db.yourCollection.update({_id: 1, currentCount: {$lt: 100}}, { $inc: { currentCount: 1 } });

$ inc 将执行增量,但仅当文档的当前状态具有值小于100的currentCount字段时,这是您在本文档的另一个字段中定义的限制。

答案 2 :(得分:1)

我认为你所谈论的案件永远不会发生。想象一下,同时会有2个请求,结果会得到99/100。然后他们都会尝试更新到100/100。您正在递增从节点脚本中的数据库获得的值,而不是直接在mongo中的值。

你也可以使用db.collection.findAndModify,但看起来没有mongoose API。

https://docs.mongodb.com/manual/reference/method/db.collection.findAndModify/