1

这是我的问题的描述:

  1. 我在负载均衡器后面有 x 个用 nodejs (express.js) 编写的网络工作者。这些工作人员将数据写入 mongodb (mongoose.js)
  2. 我已经设置了端点 y,以便在处理程序的中间件链中的某个点执行以下逻辑:如果请求用户存在于数据库中,则获取它,更新一些字段,然后将其存储回来。如果不存在,将其插入 mongo.

笔记!我无法使用 Mongoose 的 findAndUpdateOne() - 这将是原子的 - 由于域特定的逻辑,即。如果用户已经存在,用某个值更新它,否则用另一个值插入它。

  1. 问题是,来自同一用户(数据库中尚不存在)的两个请求通常会命中两个不同的工作人员。当用户处理中间件启动时,两个工作人员都会确定用户不存在并尝试插入它然后更新它。这自然会导致错误,例如。验证错误:我为每个用户验证和其他设置了一个唯一的电子邮件。

我怎样才能防止这种情况?

4

1 回答 1

2

您可以使用$set$setOnInsert更新运算符来实现这一点。

来自MongoDB $setOnInsert 文档

如果带有 upsert: true 的更新操作导致插入文档,则 $setOnInsert 将指定的值分配给文档中的字段。如果更新操作没有产生插入,$setOnInsert 什么也不做。

如果带有 upsert: true 的 db.collection.update() 找到了匹配的文档,则 MongoDB 执行更新,应用 $set 操作但忽略 $setOnInsert 操作。

所以,这应该可以解决问题:

var now = Date.now();

Users.update({ _id: 1 }, {
  $set:         { updatedAt: now },
  $setOnInsert: { createdAt: now }
}, {upsert: true}, function(err, doc) {

  // resultant doc is available here

})
于 2015-01-29T23:24:50.707 回答