web-dev-qa-db-ja.com

MongoDBコレクション内のすべてのドキュメントでキーの値を合計する方法

MongoDBにコレクションがあります:

{ "_id" : ObjectId("4d2407265ff08824e3000001"), "subida" : 3.95 }
{ "_id" : ObjectId("4d2551b4ae9fa739640df821"), "subida" : 6.03 }
{ "_id" : ObjectId("4d255b115ff08821c2000001"), "subida" : 5.53 }
{ "_id" : ObjectId("4d25e8d55ff08814f8000001"), "subida" : 1.96 }

キーの値を合計する方法、たとえば"subida"、すべてのドキュメントにわたって?上記のドキュメントを使用して、次の行に沿って何かを受け取る必要があります。

{ "subida" : 17.47 }
40
JAM

私は個人的にコレクションに対してmapreduceを実行します:

mapは、「subida」フィールドを出力する単純な関数です。単一の合計が必要な場合、キーは同じでなければなりません。 reduceの後の結果は、単一のオブジェクト{<key>: <sum>}を生成します。<key>は、emitで指定した値です。

map = function() { emit(<key>, this.subida); }

reduceはそれらを合計する単純な関数でもあります:

red = function(k, v) {
  var i, sum = 0;
  for (i in v) {
    sum += v[i];
  }
  return sum;
}

コレクション<mycollection>でmapreduceを呼び出すことができます:

res = db.<mycollection>.mapReduce(map, red);

これにより、他のコレクションと同様に操作できる一時的な新しいコレクションが作成されます。 mapReduceによって返される値には、経過時間、ステータスなどのmapReduceに関するいくつかの値、およびtempが保持されます。 「結果」フィールドに作成されたコレクション名。必要な値を取得するには、そのコレクションをクエリする必要があります。

db[res.result].find()

オブジェクト{<key>: <sum>}が得られます。

MongoDB 1.7.4以降を実行している場合、MongoDBにコレクションを作成せずに直接結果を返すように要求することで、少し手間を省くことができます。

db.<mycollection>.mapReduce(map, red, {out : {inline: 1}});
16
Yochiro

この場合、集約はmapReduceよりもはるかに単純で効率的です。

db.collection.aggregate({
    $group: {
        _id: '',
        subida: { $sum: '$subida' }
    }
 }, {
    $project: {
        _id: 0,
        subida: '$subida'
    }
})
  1. $ groupを$ sumとともに使用して合計を計算する
  2. プロジェクションの$ project演算子を使用して、$ group演算子に必要なidキーを削除します
117
Ilya Builuk

オプション0: MongoDB集約パイプライン を使用します
[注:このオプションは、この質問が尋ねられてからかなり後に追加されましたが、現在は適切なアプローチです]


オプション1:すべてのレコードをクエリし、Mongoからsubidaフィールドのみを返し、Mongoカーソルクライアント側で繰り返してそれらを加算します。

オプション2:subdiaフィールド(すべてのキーが同じ)のみを出力するmap reduceコマンドを作成し、それらを合計するreduceコマンドを作成します。

オプション3:db.evalを使用して、サーバーでjavascriptを実行します。 http://www.mongodb.org/display/DOCS/Server-side+Code+Execution

オプション4:コレクションに値を挿入するときに「subida」値を累積して、必要なときにいつでも最新の合計値を手に入れるようにします。合計を別のドキュメントに保存し、アトミックな「現在の場合は更新」操作を使用して更新できます。 http://www.mongodb.org/display/DOCS/Atomic+Operations

6
Ian Mercer

コレクションを配列として使用できます。ループに値を追加するだけです。

編集:はい、これは大きなデータセットを使用する場合の悪い習慣です。

0
oscarcardoso

この最も単純なクエリを使用して、結果の合計を取得します

db.collection.aggregate({
    $group: {
        _id: '',
        subida: { $sum: '$subida' }
    }
 }
)
0
Shakthifuture