我正在编写第二个mapReduce,以从包含“活动”嵌套文档的集合中获取上周为每位用户播放的前十首歌曲,该文档包含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) {};

最佳答案

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

为了简化调用,在MapReduce中,映射器函数获取输入并通过键对其进行拆分,然后将(key,value)对传递给reducer。然后,reducer将(key, [list of values])对聚合为一些有用的输出。

在您的情况下,key是用户ID,值是他们听过的前10首歌曲。只是按照数据布局的方式,它已经被组织成(key,[list of values])对。您已经有了键,键之后是与它关联的每个值的列表。用户ID随他们收听的每一首歌曲一起列出,因此无需减少。

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

关于javascript - MapReduce误解。,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12563402/

10-12 12:47
查看更多