我在当前项目中遇到mongo更新问题。我们在MongoDB中维护了一个文档池。读取器进程从此池中提取一批文档。为了确保不再提取DB中的文档,将更改与每个文档关联的状态(例如,从“到达”到“处理”)。
我们正在考虑扩展并让多个读取器进程获取不同的批次。但是,根据我的理解,mongo更新在批处理上不是原子的。我有什么办法可以实现这个目标吗?我需要确保在前一个文档更新之前,不同的阅读器不会从池中拾取文档。我基本上是在查看原子批量更新。 谢谢!
答案 0 :(得分:1)
据推测,你正在做这样的事情来更新雕像:
db.docs.update({status:"arrived"},{$set:{status:"processing"}},{multi:true})
然后加载状态为“processing”的文档。
目前没有mongo咒语可以更新多个但少于所有匹配文档。您可以对所有文档使用{multi:true}
,或者只标记一个文档。
鉴于此,您可以尝试使用非多重更新为每个阅读器进程标记具有唯一ID的到达文档。然后阅读要处理的文档。标记将以一个读者的唯一ID原子更新一个文档,从而避免读者之间的争用。
类似的东西:
db.docs.update({status:"arrived"},{$set:{status:"processing", readerId:<myid>}})
其中<myid>
是发出此mongo更新的读者进程的唯一ID值。
然后读者可以加载文档:
db.docs.find({status:"processing", readerId:<myid>}}
答案 1 :(得分:0)
如果您使用findAndModify
,则可以原子方式查找和更新文档。
如果你
db.docs.findAndModify({
query : {'status':'arrived' },
sort: { dateTimeOfdoc:-1},
update : { 'status':'processing','transactionId':12345},
new : true});
虽然所有线程都在竞争文档,因为每个文档都可以在原子操作中找到并修改,这意味着一旦线程拥有它,它就不会被其他人获取。
这不是您想要的一批文档,但是它是否可以处理您的问题?