2013-08-29 134 views
16

我想写一个聚合来识别使用多个支付来源的帐户。典型的数据是。现在MongoDB聚合:计数不同的字段

{ 
account:"abc", 
vendor:"amazon", 
} 
... 
{ 
account:"abc", 
vendor:"overstock", 
} 

,我想产生类似这样

{ 
account:"abc", 
vendorCount:2 
} 

帐户列表我怎么会写这在蒙戈的聚合框架

回答

46

我想通了这一点,通过使用$ addToSet和$ unwind操作符。

Mongodb Aggregation count array/set size

db.collection.aggregate([ 
{ 
    $group: { _id: { account: '$account' }, vendors: { $addToSet: '$vendor'} } 
}, 
{ 
    $unwind:"$vendors" 
}, 
{ 
    $group: { _id: "$_id", vendorCount: { $sum:1} } 
} 
]); 

希望它可以帮助别人

+0

这对于集合,其中一组的情意是足够小的工作,但对于大数据情况下,这是不行的(想象一下,如果你有数十万独特的供应商)。 –

+3

这个答案解决了大数据场景:http://stackoverflow.com/a/24770233/139721 – anushr

+0

是否真的有必要再次迭代'$ vendors'?因为我们可以通过'results.get(“vendors”)。size();' –

14

我认为它的更好,如果你执行的查询像下面这将避免开卷

db.t2.insert({_id:1,account:"abc",vendor:"amazon"}); 
db.t2.insert({_id:2,account:"abc",vendor:"overstock"}); 


db.t2.aggregate(
{ $group : { _id : { "account" : "$account", "vendor" : "$vendor" }, number : { $sum : 1 } } }, 
{ $group : { _id : "$_id.account", number : { $sum : 1 } } } 
); 

,它会显示你下面的结果预计。

{ "_id" : "abc", "number" : 2 } 
5

我不明白为什么有人会要使用$组两次

db.t2.aggregate([ { $group: {"_id":"$account" , "number":{$sum:1}} } ]) 

这将完全正常工作。

+0

我想应该是因为他们想重新命名密钥并重新格式化。但事实上,这确实更好,更有效。 – c24b

+9

我认为他们正在寻找“独特”数量。 – user1700890

-4

一个例子

db.collection.distinct("example.item").forEach(function(docs) { 
    print(docs + "==>>" + db.collection.count({"example.item":docs})) 
}); 
+1

你应该提供一个描述来描述*为什么这可以作为问题的解决方案。使示例代码使用与实际问题相同的数据和变量上下文也非常有帮助。这个答案在StackOverflow上将被视为“低质量”;低质量的答案往往会吸引downvotes,并可能让你禁止回答任何更多的问题。 –

0

您可以使用sets

db.test.aggregate([ 
    {$group: { 
     _id: "$account", 
     uniqueVendors: {$addToSet: "$vendor"} 
    }}, 
    {$project: { 
     _id: 1, 
     vendorsCount: {$size: "$uniqueVendors"} 
    }} 
]);