2016-04-28 160 views
3

我正在尋找一種方式來獲取數據,如該如何將文檔分組到數組元素的索引上?

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

我想總結基礎上改編的第一個項目(指數)的數量。在另一個集合中,我想對arr數組中的第一個和第二個項目執行相同操作。

我試過使用展開,但分解數據和層次結構然後丟失。

我也使用

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

嘗試,但結果是空白陣列

回答

2

其實你可以不指定索引處的元素使用dot notation將你的文件。到兩個你有兩個選擇:

首先在MongoDB 3.2中使用$arrayElemAt運算符new的最佳方式。它返回數組中指定索引處的元素。

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

從MongoDB的3.0版本落後,你將需要由_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'。我認爲這可能是更好的選擇,因爲我認爲在數組中添加第二個元素會更容易,通過這樣做......'{arr_0:{$ arrayElemAt:[$ arr,0]},arr_1:{$ arrayElemAt :[$ arr,1]},} – Daniel

+0

@Daniel yes'$ arrayElemAt'絕對是最好的選擇。順便說一句,你應該考慮接受答案。 – styvane

相關問題