2013-08-29 19 views
16

Ich versuche, eine Aggregation zu schreiben, um Konten zu identifizieren, die mehrere Zahlungsquellen verwenden. Typische Daten wären.MongoDB-Aggregation: Zählen unterschiedlicher Felder

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

Nun, würde Ich mag eine Liste der Konten produzieren ähnlich wie diese

{ 
account:"abc", 
vendorCount:2 
} 

Wie würde ich dies in Mongo Aggregation Rahmen schreibe

Antwort

46

ich dies mit dem $ heraus addToSet- und $ unwind-Operatoren.

Mongodb Aggregation count array/set size

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

Hoffe, dass es jemand

+0

Diese für Sätze können funktionieren können, wo Herzlichkeit der Menge klein genug ist, aber für große Datenszenarien dies funktioniert nicht (sich vorstellen, wenn Sie hatten Hunderttausende von einzigartigen Anbietern). –

+3

Diese Antwort löst das Big-Data-Szenario: http://stackoverflow.com/a/24770233/139721 – anushr

+0

Ist es wirklich notwendig, wieder zu iterieren '$ Vendors'? Angesichts dieser Tatsache, dass wir die Anzahl der Anbieter durch 'results.get (" Lieferanten ") berechnen können. size();' –

14

hilft denke ich, es ist besser, wenn Sie ausführen Abfrage wie folgt die

Abroller vermeiden
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 } } } 
); 

Welche Sie Ergebnis folgende zeigt die voraussichtlich .

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

Ich sehe nicht, warum jemand $ Gruppe verwenden würde zweimal

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

Das funktioniert völlig in Ordnung.

+0

Ich vermutete, weil sie die Schlüssel umbenennen und neu formatieren wollten. Aber das ist tatsächlich viel besser und viel effektiver. – c24b

+9

Ich denke, dass sie nach "einzigartiger" Zählung suchten. – user1700890

-4

Ein Beispiel

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

Sie sollten eine Beschreibung angeben, um * warum * dies als Lösung für die Frage zu beschreiben. Es ist auch sehr, sehr hilfreich, dass der Beispielcode denselben Daten und Variablenkontext verwendet wie die eigentliche Frage. Diese Antwort wird in StackOverflow als "geringe Qualität" angesehen. Niedrige Qualitätsantworten neigen dazu, Downvotes anzulocken, und können Sie davon abhalten, weitere Fragen zu beantworten. –

0

Sie sets

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