我在当前项目中遇到了 mongo 更新问题。我们在 MongoDB 中维护了一个文档池。阅读器进程从该池中获取一批文档。为了确保不再从数据库中获取文档,与每个文档相关联的状态都会更改(例如,从到达到处理中)。
我们正在考虑扩大规模并让多个读取器进程拾取不同的批次。但是,根据我的理解,mongo 更新在批次上不是原子的。我有什么办法可以实现这一目标?我需要确保一个文档在被前一个阅读器更新之前不会被其他阅读器从池中提取。我基本上是在查看原子批量更新。谢谢!!
Presumably you are doing something like this to update the statue:
db.docs.update({status:"arrived"},{$set:{status:"processing"}},{multi:true})
followed by a load of the documents with status:"processing".
There currently is no mongo incantation to update more than one but fewer than all matching documents. You ether use {multi:true}
for all documents or you only mark one document.
Given that, you might try marking arriving documents with a unique id for each reader process with a non-multi update. Then read the document to process. The marking will atomically update one document with one reader's unique id thus avoiding contention between readers.
Something like:
db.docs.update({status:"arrived"},{$set:{status:"processing", readerId:<myid>}})
where <myid>
is the unique id value for the reader process that issues this mongo update.
Then the reader can load docs with:
db.docs.find({status:"processing", readerId:<myid>}}
如果您使用findAndModify
,您可以自动查找和更新文档。
如果你
db.docs.findAndModify({
query : {'status':'arrived' },
sort: { dateTimeOfdoc:-1},
update : { 'status':'processing','transactionId':12345},
new : true});
虽然所有线程都在竞争文档,因为每个文档都可以在原子操作中找到和修改,这意味着一旦一个线程拥有它,它就不会被其他人获取。
这不是您想要的一批文档,但它可以解决您的问题吗?