簡體   English   中英

是否可以在MongoDB中迭代mapReduce

[英]Is it possible to iterate over mapReduce in MongoDB

我在MongoDB中使用mapReduce為用戶通過他/她的朋友網絡生成流行歌曲。 因此,我遍歷所有用戶,並檢查user_id是否存在於其朋友數組中,如果存在,則發出他們的歌曲,然后合並發出的全部歌曲,以查找其所有朋友網絡的熱門歌曲。

問題是我需要遍歷所有用戶以查找集合中每個用戶的(網絡流行歌曲)。 我如何才能做到這一點,有沒有辦法像嵌套的mapReduce一樣。 還是我必須從應用程序層進行迭代,例如通過for循環執行mapReduce!

我當前使用的mapReduce是這個:

var map = function() {
users = [];
songs = [];
    if(this.value.friends !== undefined && this.value.friends.length !== 0 && this.value.songs !== undefined && this.value.songs.length !== 0){
        key = this._id.user_id;
        for(var x=0; x<this.value.songs.length; x++)
            emit({user_id:user_id,song_id:this.value.songs[x][0]},{played:this.value.songs[x][1], counter:1});
    }
};
var reduce = function(key, values) {
    var counter = 0;
    var played = 0;
    values.forEach(function(val){
        counter += val.counter;
        played += val.played;
    });
    return {played : played, counter : counter};
};
db.runCommand({"mapreduce":"trending_users", "map":map, "reduce":reduce, "scope":{user_id: "111222333444"} ,"query":{'value.friends':{$in : ['111222333444'] }},'out':{merge:'trending_user_network'}})    
db.trending_user_network.find({'_id.user_id':'111222333444'}).sort({'value.counter':-1, 'value.played':-1})

當然,您可以在應用程序中使用for循環來遍歷用戶ID並為每個ID運行地圖縮減。 但是,對於這樣的事情,使用聚合框架來創建聚合操作的管道以一次完成所有操作可能會更好。

我不知道您的架構的確切細節,但是我認為您可以按照以下方式建立一個聚合管道:

  • $unwind獲取映射到其朋友的用戶ID的平面用戶列表
  • 再次$unwind將朋友的用戶ID映射到他們的歌曲列表
  • $group獲取結果列表中每首歌曲的匯總
  • $sort將結果排序

實際上,您的管道可能需要更多的步驟,但是我認為,如果您從聚合而不是map-reduce的角度來看這個問題,它將更加容易。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM