2016-04-28 15 views
3

私はそのような私はARRの第1項目(指標)に基づいて、カウントを合計したいと思い、この配列要素のインデックスにドキュメントをグループ化する方法は?

{ "_id" : 5, "count" : 1, "arr" : [ "aga", "dd", "a" ] }, 
{ "_id" : 6, "count" : 4, "arr" : [ "aga", "ysdf" ] }, 
{ "_id" : 7, "count" : 4, "arr" : [ "sad", "aga" ] } 

としてデータを取るための方法を探しています。別の集計では、arr配列の1番目と2番目の項目で同じことをしたいと思います。

unwindを使用しようとしましたが、データが分割され、階層が失われます。

私も

$group: { 
    _id: { 
     arr_0:'$arr.0' 
    }, 
    total:{ 
     $sum: '$count' 
    } 
} 

を使用して試してみたが、結果は空白の配列

答えて

2

実際にあなたが指定したインデックスにある要素によってグループにあなたの文書をdot notationを使用することはできませんです。 2つのオプションには2つのオプションがあります:

最初にMongoDB 3.2の$arrayElemAtオペレータnewを使用する最適な方法。配列内の指定されたインデックスにある要素を返します。 MongoDBのバージョン3.0から

db.collection.aggregate([ 
    { "$group": { 
     "_id": { "$arrayElemAt": [ "$arr", 0 ] }, 
     "count": { "$sum": 1 } 
    }} 
]) 

後方あなたは_idで初めて$groupに、あなたの配列を非正規化し、配列内の最初の項目を返すために$first演算子を使用する必要があります。そこから、その値を使用して文書を再編成し、合計を得るには$sumを使用する必要があります。しかし、MongoDBも$last演算子を提供するため、これは最初と最後のインデックスでのみ機能します。このような何か得

db.collection.aggregate([ 
    { "$unwind": "$arr" }, 
    { "$group": { 
     "_id": "$_id", 
     "arr": { "$first": "$arr" } 
    }}, 
    { "$group": { 
     "_id": "$arr", 
     "count": { "$sum": 1 } 
    }} 
]) 

:あなたの配列内の位置pの要素を使用して、グループに

{ "_id" : "sad", "count" : 1 } 
{ "_id" : "aga", "count" : 2 } 

をあなたはmapReduce機能を使用して、より良いチャンスを得るでしょう。返し

var mapFunction = function(){ emit(this.arr[0], 1); }; 
var reduceFunction = function(key, value) { return Array.sum(value); }; 
db.collection.mapReduce(mapFunction, reduceFunction, { "out": { "inline": 1 } }) 

{ 
     "results" : [ 
       { 
         "_id" : "aga", 
         "value" : 2 
       }, 
       { 
         "_id" : "sad", 
         "value" : 1 
       } 
     ], 
     "timeMillis" : 27, 
     "counts" : { 
       "input" : 3, 
       "emit" : 3, 
       "reduce" : 1, 
       "output" : 2 
     }, 
     "ok" : 1 
} 
+0

おかげで、私は '$ arrayElemAt'のようなものを探していました。私はそれがより良い選択肢かもしれないと思うので、私は配列の2番目の要素を追加することがこの方法でもっと簡単になると思う... {arr_0:{$ arrayElemAt:[$ arr、0]}、arr_1:{$ arrayElemAt :[$ arr、1]}、} – Daniel

+0

@Danielはい '$ arrayElemAt'は間違いなく最適なオプションです。あなたは答えを受け入れることを検討すべきです。 – styvane

関連する問題