MapReduce误解。

时间:2012-09-24 10:44:01

标签: javascript mongodb mapreduce mongodb-query

我正在编写我的第二个mapReduce,以便从包含“activity”嵌套文档的集合中获取上周为每个用户播放的前十首歌曲,该文档具有song_id,counter和date数组。计数器意味着歌曲的“播放时间”。

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

1 个答案:

答案 0 :(得分:3)

您不需要reduce功能。根据输入数据,没有必要,我将解释原因。

要以简化的方式调用,在MapReduce中,映射器函数接受输入并按键将其拆分,然后将(key,value)对传递给reducer。然后,reducer将(key, [list of values])对聚合成一些有用的输出。

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

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