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。丢弃未修改的文档,它们已被并发更新声明。
假设集合中有 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。丢弃未修改的文档,它们已被并发更新声明。