直接查询MongoDB mapreduce与更新原始集合的结果

Mar*_*arc 4 mapreduce mongodb

我有一个mapreduce工作,运行在一组帖子上,并计算每个帖子的受欢迎程度.mapreduce输出一个包含每个帖子的post_id和流行度的集合.应用程序需要能够按流行度排序.有数百万个帖子,这些流行度每10分钟更新一次.我能想到的两种方法:

方法1

  1. 在帖子表的流行度字段上保留一个索引
  2. 在posts表上运行mapreduce(这将替换以前的mapreduce结果)
  3. 循环遍历mapreduce结果集合中的每一行,并在posts表中单独更新其相应帖子的流行度
  4. 直接在posts表上查询以获取按人气排序的帖子

方法2

  1. 在posts表上运行mapreduce(这将取代之前的mapreduce结果)
  2. 在生成的mapreduce集合中的流行度字段中添加索引
  3. 当应用程序需要帖子时,首先查询mapreduce结果集合以获取已排序的post_id,然后查询posts集合以获取实际的帖子数据

问题

  1. 方法1需要在posts表中维护一个流行度的索引.它还需要每10分钟左右单独更新数百万(邮局表有数百万行)的流行度.它只会更新那些已经改变了流行度的帖子,但它仍然会对带有几个索引的集合进行大量更新.此集合上还会有大量的读取数据.这可扩展吗?
  2. 对于方法2,是否可以mapreduce posts集合来创建新的流行集合,立即在其上创建索引,并查询它?
  3. 问题#2是否存在任何并发问题,假设应用程序将查询该流行度集合,因为它正在通过地图更新并重新编制索引.
  4. 如果mapreduce取代了流行度集合,我每次都需要手动创建一个新索引,或者mongo知道如何在流行度字段上保留一个索引.基本上,索引如何与mapreduce结果集合一起使用.
  5. 我可以使用一些调整或其他方法吗?

谢谢你的帮助!

Mar*_*arc 8

有关Map Reduce的一般建议是让您的应用程序对每个插入执行一些额外的计算,并尽可能避免执行处理器密集型映射减少作业.

是否可以在每个"帖子"文档中添加"受欢迎程度"字段,并且每次发布每个帖子,点击,投票或测量受欢迎程度时,您的应用程序是否会增加它?然后,您可以索引受欢迎程度字段,按受欢迎程度搜索帖子将是闪电般快速的.

如果只是增加"流行度"字段不是一个选项,并且必须执行MapReduce操作,请尝试阻止它遍历集合中的所有文档.随着收藏的增长,你会发现这变得非常缓慢.听起来好像你的收藏已经很大了.

可以执行增量映射缩减,其中最新映射缩减的结果与前一个映射的结果集成,而不是仅仅被覆盖.您还可以向mapReduce函数提供查询,因此不会读取所有文档.也许添加一个查询,该查询仅匹配自上次地图缩小以来已查看,投票或添加的帖子.

有关增量mapReduce操作的文档如下:http: //www.mongodb.org/display/DOCS/MapReduce#MapReduce-IncrementalMapreduce

"输出选项"部分介绍了如何将新结果与旧结果集成.

我知道到目前为止我的建议很普遍,所以我现在会尝试解决你的问题:

1)如上所述,如果您的MapReduce操作必须读取每个文档,这将无法很好地扩展.
2)MapReduce操作仅输出集合.创建索引并查询该集合必须以编程方式完成.3)如果有一个进程在另一个正在更新它的同时查询集合,则查询可以在更新之前返回文档.简短的回答是,"是"4)如果集合被删除,则必须重建索引.如果集合中的文档被删除,但集合本身未被删除,则索引将保持不变.在使用{out:{replace:"output"}}选项运行MapReduce的情况下,索引(ex)将保持不变,并且不必重新创建.
5)如上所述,如果可能的话,最好在"posts"集合中添加另一个字段,并更新它,而不是执行如此多的MapReduce操作.

希望我能够在构建应用程序时为您提供一些其他因素.最终,重要的是要记住每个应用程序都是独一无二的,因此,为了最终证明哪种方式是"最佳",您将不得不尝试所有不同的选项,并自己决定哪种方式最有效.祝好运!