2013-08-29 132 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"} 
    }} 
]);