大量のデータを1つのコレクションに集めようとしていましたが、そこに到達するためにMapReduce関数を書く際に問題があります。MongoDBコレクションのMapReduceが空になっています
これは私のデータは次のようになります(ここでは、実際に私が4+万人を持って、17行です):
{"user": 1, "day": 1, "type": "a", "sum": 10}
{"user": 1, "day": 2, "type": "a", "sum": 32}
{"user": 1, "day": 1, "type": "b", "sum": 11}
{"user": 2, "day": 4, "type": "b", "sum": 2}
{"user": 1, "day": 2, "type": "b", "sum": 1}
{"user": 1, "day": 3, "type": "b", "sum": 9}
{"user": 1, "day": 4, "type": "b", "sum": 12}
{"user": 2, "day": 2, "type": "a", "sum": 3}
{"user": 3, "day": 2, "type": "b", "sum": 81}
{"user": 1, "day": 4, "type": "a", "sum": 22}
{"user": 1, "day": 5, "type": "a", "sum": 39}
{"user": 2, "day": 5, "type": "a", "sum": 8}
{"user": 2, "day": 3, "type": "b", "sum": 1}
{"user": 3, "day": 3, "type": "b", "sum": 99}
{"user": 2, "day": 3, "type": "a", "sum": 5}
{"user": 1, "day": 3, "type": "a", "sum": 41}
{"user": 3, "day": 4, "type": "b", "sum": 106}
...
私は配列(それが最終的にこのように見えるように取得しようとしています内容は日によって決定された適切なインデックスでちょうど合計され、各タイプ、その日はそのタイプのために存在しない場合、それは)ちょうど0だため:
{"user": 1, "type_a_sums": [10, 32, 41, 22, 39], "type_b_sums": [11, 1, 9, 12, 0]}
{"user": 2, "type_a_sums": [0, 3, 5, 0, 8], "type_b_sums": [0, 0, 1, 2, 0]}
{"user": 3, "type_a_sums": [0, 0, 0, 0, 0], "type_b_sums": [0, 81, 99, 106, 0]}
...
これは私がされているMapReduceのです試着:
var mapsum = function(){
var output = {user: this.user, type_a_sums: [0, 0, 0, 0, 0], type_b_sums: [0, 0, 0, 0, 0], tempType: this.type, tempSum: this.sum, tempDay: this.day}
if(this.type == "a") {
output.type_a_sums[this.day-1] = this.sum;
}
if(this.type == "b") {
output.type_b_sums[this.day-1] = this.sum;
}
emit(this.user, output);
};
var r = function(key, values) {
var outs = {user: 0, type_a_sums: [0, 0, 0, 0, 0], type_b_sums: [0, 0, 0, 0, 0], tempType: -1, tempSum: -1, tempDay: -1}
values.forEach(function(v){
outs.user = v.user;
if(v.tempType == "a") {
outs.type_a_sums[v.tempDay-1] = v.tempSum;
}
if(v.tempType == "b") {
outs.type_b_sums[v.tempDay-1] = v.tempSum;
}
});
return outs;
};
res = db.sums.mapReduce(mapsum, r, {out: 'joined_sums'})
これは私の小さなサンプルで私の出力が得られますが、私はすべて400万それを上に実行したときに、私は次のようになり出力のトンを得る:
users
の大部分を持っている必要があり
{"user": 1, "type_a_sums": [0, 0, 0, 0, 0], "type_b_sums": [0, 0, 0, 0, 0]}
{"user": 2, "type_a_sums": [0, 3, 5, 0, 8], "type_b_sums": [0, 0, 1, 2, 0]}
{"user": 3, "type_a_sums": [0, 0, 0, 0, 0], "type_b_sums": [0, 0, 0, 0, 0]}
それらの配列の合計は、実際には実際の関数でそれを埋める前にreduce
関数outs
オブジェクトのダミー配列にあった0で埋められています。
同じコレクションで同じ正確な関数を実行しても1人のユーザーのみを確認すると、実際には奇妙です。res = db.sums.mapReduce(mapsum, r, {query: {user: 1}, out: 'joined_sums'})
配列に合計があるはずですが、以前はすべて0になっていますそのユーザーのために必要な出力。 4百万を超えるすべてを再び実行して、私はどこにでも戻ってきます。ダミーフィラーアレイで行ったすべての作業を書いているようなものです。
データが多すぎますか?それは時間を与えられてそれをスロッグすることはできませんか?それとも私は知らない障壁に当たっていますか?
MongoDBの古いバージョンのバグ? – maerics
私は 'reduce()'がキーごとに複数回呼び出されることと関連があると思います。私は 'finalize'を使用しようとしていますが、どのように動作するのか非常に混乱しています。 – TFX