1

我有大约 500 条这种格式的记录:

{
     "_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},
                    ]
            }

请注意,设备数组有对象,每个对象都有一个字符串一个计数。在上面的示例中,设备在“AT&FU (US)”的集合中SomeString1具有83“发生次数”carrier

目前,我能找到的只是carrier“AT&FU (US)”有 392 个“SomeStringX”与之关联。

是否可以通过对聚合管道的子调用来做到这一点,还是我需要使用 map reduce?如果我需要做map reduce,我会怎么做?

4

1 回答 1

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"}}   
     }
)
于 2013-06-05T05:41:02.790 回答