【问题标题】:MapReduce misconception.MapReduce 的误解。
【发布时间】:2012-09-24 10:44:01
【问题描述】:

我正在编写我的第二个 mapReduce,以从包含“活动”嵌套文档的集合中获取上周为每个用户播放的前十首歌曲,该文档包含一组 song_id、计数器和日期。 Counter 表示歌曲的“播放次数”。

我尝试使用 mapReduce,我能够完成此任务并仅使用“map”输出所需的结果,而无需减少发出的值。这是我使用的错误方法吗?这样做的最佳方法是什么。

这里是地图功能:

var map = function() {
user_top_songs = [];
user_songs = [];
limit = 10;
if(this.activities !== undefined){
        key = {user_id:this.id};
        for (var i=0; i < this.activities.songs.length; i++){
            if (this.activities.songs !== undefined  && this.activities.songs[i].date.getDate() > (new Date().getDate()-7))
                user_songs.push([this.activities.songs[i].song_id, this.activities.songs[i].counter]);
        }
        if(user_songs.length !== 0){
            user_songs.sort(function(a,b){return b[1]-a[1]});
            if(user_songs.length < 10 )
                limit = user_songs.length;
            for(var j=0; j < limit; j++)
                user_top_songs.push(user_songs[j]);
        }
        value = {songs:user_top_songs};
        emit(key,value);
    }
}

这里是空reduce方法:

var reduce = function(key, values) {};

【问题讨论】:

  • 为了帮助我们理解手头的问题,您能否发布一个示例文档以及 MR 的结果?
  • 这里是一个示例文档paste2.org/p/2268907 最重要的部分是嵌套活动文档。

标签: javascript mongodb mapreduce mongodb-query


【解决方案1】:

您不需要reduce 函数。根据输入的数据,这不是必需的,我会解释原因。

简单地回忆一下,在 MapReduce 中,mapper 函数获取输入并按键拆分,然后将 (key,value) 对传递给 reducer。然后,reducer 将 (key, [list of values]) 对聚合成一些有用的输出。

在您的情况下,key 是用户 ID,值是他们听过的前 10 首歌曲。就数据的布局方式而言,它已经被组织成(key,[list of values]) 对。您已经拥有键,其中包含与之关联的每个值的列表。用户 ID 列在他们听的每首歌曲之后,因此无需减少。

基本上,reduce 步骤将每个 (user ID, song) 对组合成用户歌曲列表。但这已经完成了。这是数据中固有的。因此,在这种特定情况下,映射器是完成您在这种情况下所需的唯一必要功能。

【讨论】:

    猜你喜欢
    • 2014-09-05
    • 2010-09-06
    • 2014-04-03
    • 2014-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多