所以我的朋友和我正试图做一个映射减少的集合,有项目被添加到它一致。
基本上,我们计算一些字段的平均值,并把它们放在一个集合中(通过map reduce)。
这就是问题所在,每次map reduce运行时,它都会遍历所有文档。我是map reduce的新手,但根据我所知道的,如果它只在新的和/或修改的文档上运行map reduce,并使用现有的集合更新它们,似乎会非常高效。
所以我想,好吧,我就自己做吧。在集合中添加了一个"processed: false",当map reduce运行时,我传入一个查询过滤器"{processed:false}",然后在map reduce运行后,我将"{processed:true}"设置为processed = false的所有项。
问题在这里。我担心的是边缘情况。如果在地图减少过程中添加了一些物品到集合中会发生什么?它们从未被传递到map reduce中,现在map reduce运行后,它们的processed标志被设置为true。
如果不是传递一个"查询过滤器"到mongo,我将能够传递一个查询对象"set",那么我可以将处理标志设置为true,然后传递这些对象。
让它分成三步。有3个状态,例如UNPROCESSED, MARKEDFORPROCESSING和PROCESSED,然后:
- db.col。update({processingState:UNPROCESSED}, {$set:{processingState:MARKEDFORPROCESSING}}, false, true)
- 对MARKEDFORPROCESSING文档运行m/r。这些保证在m/r开始时就在那里。
- db.col。update({processingState:MARKEDFORPROCESSING}, {$set:{processingState:PROCESSED}}, false, true)
- 转到1
这避免了你的边缘情况,并且给定MongoDB的原子更新是完全安全的。