2013-06-05 41 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

我的荣幸。关于这种聚合技巧的一件很酷的事情是,一旦你看到它,你就会意识到它如何用于各种有用的多级聚合...... –