2013-06-05 274 views
1

我有這種格式的約500個記錄:mongoDB - 聚合上的聚合?

{ 
    "_id" : ObjectId("51ac1356c59151b66c0c9b6b"), 
    "device" : "SomeString", 
    "carrier" : "Cell C(ZA)" 
} 

我所尋找的是在不同的運營商的列表,每個載波設備的數量和每個設備

設備的計數

這裏是到目前爲止,我已經試過:

db.records.aggregate(
    { $project : { 
     carrier : 1, 
     device : 1, 
    } }, 
    { $group : { 
     _id : { carrier : "$carrier" }, 
     numDevice : {$sum:1}, 
     devices : { $addToSet : "$device"} 
    } }, 
    { $sort: { numDevice: 1 } 
}); 

下面是輸出:

{ "result" : [ 
      { 
        "_id" : { 
          "carrier" : "Saudi Telecom Company (SA)" 
        }, 
        "numDevice" : 229, 
        "devices" : [ 
          "SomeString1", 
          "SomeString2 
        ] 
      }, 
      { 
        "_id" : { 
          "carrier" : "AT&FU (US)" 
        }, 
        "numDevice" : 392, 
        "devices" : [ 
          "SomeString1", 
          "SomeString2", 
          "SomeString3" 
        ] 
      } 

], "ok" : 1 } 

非常接近我需要/想,但理想情況下,我希望看到每個「設備」部分是這樣的:

  { 
        "_id" : { 
          "carrier" : "AT&FU (US)" 
        }, 
        "numDevice" : 315, 
        "devices" : [ 
         {"SomeString1", 83}, 
         {"SomeString2", 17}, 
         {"SomeString5", 215}, 
        ] 
      } 

注意,設備數組對象,每個對象都有一個字符串一個計數。在上面的例子中,設備SomeString1具有收藏爲在83'出現「AT & FU(美國)」 carrier

目前,所有我能找到的是,carrier「AT & FU(美國)」有392與其關聯的「SomeStringX」。

是可以做到這一點與聚合管道的子調用,或者我是否需要使用映射減少?如果我需要做地圖縮減,我該如何去做呢?

+0

你可以用聚合框架來做到這一點。我可以發佈答案,或者我可以先給你一個提示,如果你想嘗試自己弄清楚這一點...... –

回答

4

下面介紹如何操作。關鍵是(a)你需要做$ group兩次,(b)你需要首先$ group你想要的小計,然後$ group得到總計。

db.records.aggregate(
    {$group: 
     {_id : {d:"$device",c:"$carrier"}, 
     subtotal:{$sum:1}} 
    }, 
    {$group: 
     {_id:"$_id.c", 
     devices:{$push:{device:"$_id.d", subtotal:"$subtotal"}}, 
     total:{$sum:"$subtotal"}} 
    } 
) 
+0

**謝謝**這是_exactly_我​​所需要的。我知道我可以管理多個組請求,我只是不認爲每個設備*和*運營商都有第一個ID。除非我還沒有15個'聲譽'點,否則我會加入這個計劃。 **許多感謝** – user1521764

+0

我的榮幸。關於這種聚合技巧的一件很酷的事情是,一旦你看到它,你就會意識到它如何用於各種有用的多級聚合...... –