我的用例如下 - 我在 mongoDB 中有一组文档,我必须发送这些文档进行分析。 文件格式如下-
{ _id:ObjectId("517e769164702dacea7c40d8") , 日期:“1359911127494”, 状态:“可用”, 其他字段... }
我有一个阅读器进程,它选择按 date 排序的 status:available 的前 100 个文档,并使用 status:processing 修改它们。 ReaderProcess 发送文档进行分析。分析完成后,status 将更改为 processed。
当前阅读器进程首先获取 100 个按 date 排序的文档,然后在循环中将每个文档的 status 更新为 processing。这种情况有没有更好/更有效的解决方案?
此外, future 为了可扩展性,我们可能会使用多个读取器进程。 在这种情况下,我希望一个阅读器进程选择的 100 个文档不应该被另一个阅读器进程选择。但是现在获取和更新是单独的查询,所以很可能多个读取器进程选择相同的文档。
Bulk findAndModify(有限制)可以解决所有这些问题。但不幸的是,它还没有在 MongoDB 中提供。这个问题有解决办法吗?
最佳答案
正如你提到的,目前没有干净的方法可以做你想做的事。目前,对于您需要的操作,最好的方法是:
e.g. update({_id:{$in:[<result set ids>]}, state:"available", $isolated:1}, {$set:{readerId:<your reader's ID>, state:"processing"}}, false, true)
) 标记 1) 返回的文档请注意,这甚至适用于高度并发的情况,因为阅读器永远无法保留尚未被其他阅读器保留的文档(请注意,步骤 2 只能保留当前可用的文档,并且写入是原子的)。如果您希望能够使预订超时(例如对于阅读器可能崩溃/失败的情况),我也会添加一个带有预订时间的时间戳。
编辑:更多细节:
如果写入需要相对较长的时间,则所有写入操作偶尔会为挂起的操作生成。这意味着除非您采取以下步骤,否则步骤 2) 可能看不到步骤 1) 标记的所有文档:
另请参阅有关原子性/隔离性讨论的评论。我错误地认为多重更新是孤立的。它们不是,或者至少默认情况下不是。
https://stackoverflow.com/questions/16334045/
相关文章:
mongodb - 当父字段未知时,在嵌套文档中查找具有字段的记录
mongodb - Spark 流 : foreachRDD update my mongo RDD
performance - 字段类型在 MongoDB 索引中是否重要?
javascript - MongoError : cannot change _id of a d
ruby-on-rails - MongoDB 的最佳分析/数据可视化库
mongodb - 在集合之间移动文档是表示 MongoDB 中状态变化的好方法吗?
javascript - Mongoose 连接到 MongoDB Atlas 的最佳池大小是多少?
javascript - 在 MongoDB 中按字母顺序对文档进行排序(也称为自然排序顺序,人类排