2013-08-29 8 views
16

Próbuję zapisać agregację, aby zidentyfikować konta korzystające z wielu źródeł płatności. Typowe dane byłyby.Agregacja MongoDB: Zliczanie różnych pól

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

Teraz chciałbym stworzyć listę kont podobnej do tej

{ 
account:"abc", 
vendorCount:2 
} 

Jak piszę to w ramach agregacji Mongo za

Odpowiedz

46

I zdobione to za pomocą $ addToSet i $ unwind operatorzy.

Mongodb Aggregation count array/set size

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

Mam nadzieję, że ktoś pomoże

+0

ten może pracować dla zestawów gdzie serdeczność zestawu jest na tyle niewielka, ale dla dużych scenariuszy danych to nie zadziała (wyobraźcie sobie, miałeś setki tysięcy unikalnych dostawców). –

+3

Ta odpowiedź rozwiązuje scenariusz dużych zbiorów danych: http://stackoverflow.com/a/24770233/139721 – anushr

+0

Czy naprawdę należy powrócić do iterowania '$ vendors'? biorąc pod uwagę fakt, że możemy obliczyć liczbę dostawców za pomocą 'results.get (" vendors "). size();' –

14

myślę, że lepiej, jeśli wykonać kwerendy jak po co pozwoli uniknąć odwijania

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

Który będzie można pokazać następujący wynik, który jest oczekiwany .

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

ja nie rozumiem, dlaczego ktoś miałby używać $ grupę dwukrotnie

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

To będzie działać perfekcyjnie.

+0

Przypuszczam, że chcieli zmienić nazwę klucza i sformatować go ponownie. Jest to jednak znacznie lepsze i skuteczniejsze. – c24b

+9

Myślę, że szukali oni "unikalnej" liczby. – user1700890

-4

Przykładem

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

Powinieneś podać opis opisujący * dlaczego * działa to jako rozwiązanie dla pytania. Bardzo pomocny jest również kod przykładowy wykorzystujący te same dane i kontekst zmienny, co rzeczywiste pytanie. Ta odpowiedź zostanie uznana za "niską jakość" w StackOverflow; odpowiedzi o niskiej jakości mają tendencję do przyciągania graczy w dół i mogą spowodować, że nie będziesz mógł odpowiedzieć na więcej pytań. –

0

Można użyć sets

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