Mongo findAndUpdateMany 原子地

Mongo findAndUpdateMany atomically

假设集合中有 10000 个文档。我有 3 个应用程序节点在处理这些文档。我希望一份文件只处理一次。我目前的做法是,在应用程序中有一个循环,它使用 findOneAndUpdate 查询集合,找到 claimed=false 的文档,同时将它们更新为 claimed=true。它有效,但问题是一个一个地查询文档很慢。我想做的是“找到多达 100 个 claimed=false 的文档,同时将它们更新为 claimed=true”。我需要它是原子的,以避免多个应用程序节点声明相同文档的竞争条件。但是从 Mongo 的文档中我找不到像 findManyAndUpdate() 这样的东西。在 SQL 个世界中,它基本上是 select for update skip locked。有这样的东西吗?也许我可以以某种方式利用 Mongo 的交易?

假设“找到最多”一个软限制,你可以运行 2个查询:

db.collection.find({claimed:false}, {_id:1}).limit(100)

将所有_ids放入数组ids,然后

db.collection.updateMany({claimed: false, _id: {$in: `ids`}}, {$set: {claimed: true}})

它将根据并发更新更新 0 到 100 个文档。

更新

我想我错过了一点,您实际上也需要检索文档,而不仅仅是更新它们。

没有选项,只能单独更新。 Select 100:

db.collection.find({claimed:false}).limit(100)

然后对每个 _id 进行迭代:

db.collection.updateOne({_id: id, claimed:false}, {$set: {claimed:true}})

每次更新的结果包含 modifiedCount,值为 1 或 0。丢弃未修改的文档,它们已被并发更新声明。