2011-06-30 26 views
3

以下是情况:我有一个MongoDB集群和一个Web应用程序,它执行了相当密集的Map/Reduce查询。该查询定期(每5分钟)在一个cron作业中进行,并将结果存储(使用$merge)到一个集合中。地图中的原子性/减少新记录(MongoDB)

什么作品:目前,查询执行其集合中的每个记录。所述集合缓慢增长为数百万行,并且每次运行时花费更长的时间。

明显的解决方案是在新记录上运行Map/Reduce,并使用reduce函数对旧存储值进行计算以计算正确的值。 MongoDB非常棒,它可以让你指定一个reduce选项而不是merge来做到这一点。

什么我不明白:如何正确执行M/R只在初始集合中的新记录。我看到两种可能的解决方案,但都不是很好。想法?

  1. 我可以标记已处理的记录。问题是如何标记与我刚刚M/R'd完全相同的记录?
  2. 我可以查询匹配的项目,然后将ID列表作为$in: [id1, id2, ...]查询传递给Map/Reduce,然后发送更新以使用相同的$in设置我的标志。但是那真的很不雅,而且我不知道在记录列表很大时该如何执行。

TL;博士:如何,我只在地图上选择新的记录/缩小查询降低其结果到一个集合。

回答

2

在IRC频道#mongodb上的一位善良的灵魂帮助我指出了这一点。一个简单的解决方案是有一个状态机领域,并执行以下操作(伪代码):

set {state:'processing'} where {state:{$exists:false}} 
mapreduce {...} where {state:'processing'} 
set {state:'done'} where {state:'processing'} 

现在,这是最理想的,因为它浪费了大量的磁盘空间上数以百万计的记录的集合。但真正的问题是,为什么我不早点想到这一点?

+2

我向IRC上的某个人提出了这个解决方案,它可能是你......顺便说一下,你可以使用布尔型来表示状态,所以你不会浪费太多空间。 –