我有一个mapreduce作业,可以在一系列帖子上运行并计算每个帖子的受欢迎程度。 mapreduce输出一个包含每个帖子的post_id和流行度的集合。应用程序需要能够按流行度排序。有数百万个帖子,这些流行度每10分钟更新一次。我能想到的两种方法:
问题
感谢您的帮助!
答案 0 :(得分:7)
有关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操作。
希望我能够在构建应用程序时为您提供一些其他因素。最终,重要的是要记住每个应用程序都是独一无二的,因此,为了最终证明哪种方式是“最佳”,您将不得不尝试所有不同的选项,并自己决定哪种方式最有效。祝你好运!