1

私は 2 番目の mapReduce を作成して、song_id、counter、および date の配列を持つ「アクティビティ」のネストされたドキュメントを含むコレクションから、すべてのユーザーが先週再生した上位 10 曲を取得しています。カウンターは曲の「再生時間」を意味します。

私は mapReduce を使用しようとしましたが、このタスクを達成し、出力された値を減らす必要なく、「マップ」のみを使用して必要な結果を出力することができました。これは私が使用している間違ったアプローチですか? これを行う最善の方法は何ですか。

マップ関数は次のとおりです。

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 ではマッパー関数が入力を受け取り、それをキーごとに分割してから、(key,value)ペアをレデューサーに渡します。次に、リデューサーは(key, [list of values])ペアをいくつかの有用な出力に集約します。

あなたの場合、keyはユーザー ID であり、値はユーザーが聴いた上位 10 曲です。ちょうどデータがレイアウトされているだけで、すでに(key,[list of values])ペアに編成されています。それに続くそれに関連付けられているすべての値のリストを持つキーが既にあります。ユーザー ID は、ユーザーが聴いているすべての曲の直後にリストされているため、減らす必要はありません。

基本的に、reduceステップ(user ID, song)各ペアをユーザーの曲のリストに結合することです。しかし、それはすでに行われています。それはデータに固有のものです。したがって、この特定のケースでは、マッパーは、このケースで必要なことを達成するために必要な唯一の機能です。

于 2012-09-26T17:31:05.327 に答える