1

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

我尝试使用 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) {};
4

1 回答 1

3

你不应该需要一个reduce函数。根据输入数据,这不是必需的,我将解释原因。

简而言之,在 MapReduce 中,mapper 函数获取输入并通过键将其拆分,然后将对传递(key,value)给 reducer。然后,reducer 将这些(key, [list of values])对聚合成一些有用的输出。

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

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

于 2012-09-26T17:31:05.327 回答