映射中的原子性/减少新记录(MongoDB)

时间:2011-06-30 18:12:59

标签: php mongodb mapreduce

情况就是这样:我有一个MongoDB集群和一个web-app,它可以进行非常密集的Map / Reduce查询。此查询在cron作业中定期(每5分钟)发生一次,结果将(使用$merge)存储到集合中。

什么有效:目前,查询会对其集合中的每条记录执行操作。所述集合正在慢慢增长到数百万行,每次运行时,它需要更长的时间。

显而易见的解决方案是对新记录运行Map / Reduce,并对旧存储值使用reduce函数来计算正确的值。 MongoDB很棒,它允许您指定reduce选项而不是merge来执行此操作。

我无法弄清楚:如何仅对初始集合中的新记录正确执行M / R.我看到两种可能的解决方案,两者都不好。想法?

  1. 我可以标记已处理的记录。问题是如何标记我刚刚M / R结束的完全相同的记录?
  2. 我可以查询匹配的项目,然后将id列表作为$in: [id1, id2, ...]查询传递给Map / Reduce,然后发送更新以使用相同的$in设置我的标记。但这真的很不优雅,而且我不知道当记录列表很大时它会如何执行。
  3. tl; dr:我如何只在Map / Reduce查询中选择新记录,将其结果缩减为集合。

1 个答案:

答案 0 :(得分:2)

#mongodb IRC频道上的善良帮助我解决了这个问题。一个简单的解决方案是拥有一个状态机字段,并执行以下操作(伪代码):

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

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