0

私は開発でmongodb2.0.4を使用してきましたが、本番環境にデプロイしたときに、2.2.0が実行されていることに気づきませんでした。私が使用していたmapReduce関数は、2.0.4未満であったため動作しなくなり、その理由がわかりません。

mongodb 2.0.4(注:M、F、T、I、C、H、R、Dの合計は144であり、この例ではそうです):

{
"_id" : "",
"value" : {
    "tag" : "",
    "networth" : 43558505,
    "land" : 201837,
    "alive" : 144,
    "M" : 86,
    "F" : 6,
    "T" : 5,
    "I" : 10,
    "C" : 17,
    "H" : 4,
    "R" : 12,
    "D" : 4,
    "gdi" : 15
    }
}

mongo 2.2.0(m + f + t + i + c + h + r + dの合計は最大108、合計144になるはずです)

{
"_id" : "",
"value" : {
    "tag" : "",
    "networth" : 43558505,
    "land" : 201837,
    "alive" : 144,
    "M" : 67,
    "F" : 5,
    "T" : 3,
    "I" : 6,
    "C" : 13,
    "H" : 3,
    "R" : 9,
    "D" : 2,
    "gdi" : 15
    }
}

これが私が使用しているmap/reduce関数です:

// Map function
var map = function() { 
    var key = this.tag;
    var value = 
    {
        tag: this.tag,
        networth: this.networth,
        land: this.land,
        alive: this.alive,
        gdi: this.gdi,
        gov: this.gov
    };
    emit(key, value);
};

機能を減らす

var reduce = function(k,vals) {
    reducedVals = { tag: k, networth: 0, land: 0, alive: 0, M: 0, F: 0, T: 0, I: 0, C: 0, H: 0, R: 0, D: 0, gdi: 0 };

    for (var i = 0; i < vals.length; i++){

        reducedVals.networth += vals[i].networth;
        reducedVals.land += vals[i].land;
        reducedVals.alive += vals[i].alive;
        reducedVals.gdi += vals[i].gdi;     
        if (vals[i].gov == "M") reducedVals.M = reducedVals.M + 1;
        if (vals[i].gov == "F") reducedVals.F = reducedVals.F + 1;
        if (vals[i].gov == "T") reducedVals.T = reducedVals.T + 1;
        if (vals[i].gov == "I") reducedVals.I = reducedVals.I + 1;
        if (vals[i].gov == "C") reducedVals.C = reducedVals.C + 1;
        if (vals[i].gov == "H") reducedVals.H = reducedVals.H + 1;
        if (vals[i].gov == "R") reducedVals.R = reducedVals.R + 1;
        if (vals[i].gov == "D") reducedVals.D = reducedVals.D + 1;
    }
    return reducedVals;
};

マップリデュースを実行します

collection.mapReduce(map, reduce, {out: {replace : 'alliances'}, query: {"alive":1}}, function(err, collection) {
    // Mapreduce returns the temporary collection with the results
            db.close();
     }); 

簡単に説明すると、コレクションには次の形式のスコアがたくさんあります。

    "alive" : 1,
"countryNumber" : 47,
"deleted" : 0,
"gdi" : 0,
"gov" : "C",
"land" : 20111,
"name" : "AtheistCelebratingXmas",
"networth" : 9793082,
"protection" : 0,
"rank" : 1,
"resetid" : 407,
"serverid" : 9,
"tag" : "Evolve",
"vacation" : 0

私は基本的に、、、および列を合計してグループ化しtagます。次に、列の値を確認し、D、Rなどの合計を合計します。これが2.2と2.0.4で正しく機能しない理由について、私が見逃している特別な理由はありますか?いずれにせよ、新しい集約コマンドはこれをより簡単に実行しますか?私はそれを簡単に調べて、group byを取得し、合計と列を機能させることができますが、gov列からどこから始めればよいかわかりません。networthlandalivegovtagnetworthalive

4

2 に答える 2

1

関数から返されるオブジェクトの形状は、関数emitからmap返されるオブジェクトと同じである必要がありますreduce。これは、MongoDBがmap-reduceを並列化することを決定したときに、reduce呼び出しの結果がフィードバックされる可能性があるためです。reduce

したがって、値をこのようmapにアセンブルするように変更して、次から返されるものと同じ構造になるようにする必要があります。emitreduce

var value = {
    "tag" : this.tag,
    "networth" : this.networth,
    "land" : this.land,
    "alive" : this.alive,
    "gdi" : this.gdi
};
value[this.gov] = 1;

reduceそれに応じて関数を更新します。

ところで、十分なドキュメントがあれば、これは2.0.4でも失敗したでしょう。2.2は、並列化するタイミングに異なるしきい値を使用しているだけです。

于 2013-01-03T21:31:07.857 に答える
0

私のコードがバージョン間で機能しない理由を彼が答えたので、私はJohnnyHKの答えを受け入れました。ただし、問題を解決するには、コードで変更した内容を投稿する必要があると感じました。

マップ機能:

var map = function() { 
     var key = this.tag;
     var fields = {
        tag: this.tag,
        networth: this.networth,
        land: this.land,
        alive: this.alive,
        gdi: this.gdi,
        M: 0,
        F: 0,
        T: 0,
        I: 0,
        C: 0,
        H: 0,
        R: 0,
        D: 0
      };
    if (this.gov == "M") fields["M"] = 1
    else fields["M"] = 0
    if (this.gov == "F") fields["F"] = 1
    else fields["F"] = 0
    if (this.gov == "T") fields["T"] = 1
    else fields["T"] = 0
    if (this.gov == "I") fields["I"] = 1
    else fields["I"] = 0
    if (this.gov == "C") fields["C"] = 1
    else fields["C"] = 0
    if (this.gov == "H") fields["H"] = 1
    else fields["H"] = 0
    if (this.gov == "R") fields["R"] = 1
    else fields["R"] = 0
    if (this.gov == "D") fields["D"] = 1
    else fields["D"] = 0

emit(key, fields);
};

機能の削減:

var reduce = function(k,vals) {
    reducedVals = { tag: k, networth: 0, land: 0,  alive: 0, M: 0, F: 0, T: 0, I: 0, C: 0, H: 0, R: 0, D: 0, gdi: 0}; 

    for (var i = 0; i < vals.length; i++){
        reducedVals.networth += vals[i].networth;
        reducedVals.land += vals[i].land;
        reducedVals.alive += vals[i].alive;
        reducedVals.gdi += vals[i].gdi;     
        reducedVals.M += vals[i].M;
        reducedVals.F += vals[i].F;
        reducedVals.T += vals[i].T;
        reducedVals.I += vals[i].I;
        reducedVals.C += vals[i].C;
        reducedVals.H += vals[i].H;
        reducedVals.R += vals[i].R;
        reducedVals.D += vals[i].D;

    }
    return reducedVals;

};
于 2013-01-05T05:18:01.673 に答える