2

このドキュメントのパケットの合計を集計しようとしています。

{
    "_id" : ObjectId("51a6cd102769c63e65061bda"),
    "capture" : "1369885967",
    "packets" : {
        "0" : "595",
        "1" : "596",
        "2" : "595",
        "3" : "595",
        ...
    }
}

私が得ることができる最も近いものは約です

db.collection.aggregate({ $match: { capture : "1369885967" } }, {$group: { _id:null, sum: {$sum:"$packets"}}});

ただし、合計 0 が返されますが、これは明らかに間違っています。

{ "result" : [ { "_id" : null, "sum" : 0 } ], "ok" : 1 }

すべてのパケットの合計を取得するにはどうすればよいですか?

4

2 に答える 2

3

配列ではなくオブジェクトに値があるため、mapReduce を使用する必要があります。

// Emit the values as integers

var mapFunction = 
  function() {
    for (key in this.packets) {
      emit(null, parseInt(this.packets[key]));
    }
  }

// Reduce to a simple sum

var reduceFunction = 
  function(key, values) {
    return Array.sum(values);
  }

> db.collection.mapReduce(mapFunction, reduceFunction, {out: {inline:1}})
{
    "results" : [
        {
            "_id" : null,
            "value" : 2381
        }
    ],
    "ok" : 1,
}

可能であれば、代わりに数値型の配列として値を発行する必要があります。これにより、より多くのオプション (つまり、集計) が得られ、(データセットが大きくない限り) パフォーマンスが向上する可能性があります。

于 2013-05-30T10:25:04.143 に答える
1

パケット サブドキュメントに含まれるキーの数がわからない場合、およびカウントも文字列として保存しているように見える場合 (なぜ???)、mapReduce を使用する必要があります。

何かのようなもの:

m=function() { 
    for (f in "this.packets") {
      emit(null, +this.packets[f]);
};
r=function(k, vals) { 
     int sum=0;
     vals.forEach(function(v) { sum+=v; } );
     return sum;
}

db.collection.mapreduce(m, r, {out:{inline:1}, query:{your query condition here}});
于 2013-05-30T09:37:54.447 に答える