Reputation: 3498
I have some documents like this:
{
"user": '1'
},
{ "user": '1'
},
{
"user": '2'
},
{
"user": '3'
}
I'd like to be able to get a set of all the different users and their respective counts, sorted in decreasing order. So my output would be something like this:
{
'1': 2,
'2': 1,
'3': 1
}
I think this can be done with a Mongo aggregate(), but I'm having a lot of trouble figuring out the right flow for this.
Upvotes: 72
Views: 88013
Reputation: 672
You can use the below aggregation query, It will also sort the results in decreasing order as desired.
db.collection.aggregate([
{ $group: { _id: "$user", count: { $sum: 1 } } },
{ $sort: { count: -1 } }
])
Upvotes: 5
Reputation: 103365
With MongoDb 3.6 and newer, you can leverage the use of $arrayToObject
operator and a $replaceRoot
pipeline to get the desired result. You would need to run the following aggregate pipeline:
db.collection.aggregate([
{ "$group": {
"_id": "$user",
"count": { "$sum": 1 }
} },
{ "$sort": { "_id": 1 } },
{ "$group": {
"_id": null,
"counts": {
"$push": {
"k": "$_id",
"v": "$count"
}
}
} },
{ "$replaceRoot": {
"newRoot": { "$arrayToObject": "$counts" }
} }
])
which yields
{
"1" : 2,
"2" : 1,
"3" : 1
}
Upvotes: 11
Reputation: 1207
For anyone reading this in Jan 2019 the accepted answer does not currently work in Robo3T (returns a pipeline.length - 1
error).
You must:
a) wrap the query in a set of square brackets []
b) remove .result
from the end
https://github.com/Studio3T/robomongo/issues/1519#issuecomment-441348191
Here's an update to the accepted answer by @disposer that works for me in Robo3T.
db.getCollection('collectionName').aggregate(
[ {$group : { _id : '$user', count : {$sum : 1}}} ]
)
Upvotes: 43
Reputation: 6371
You can get result (not in your required format) via aggregation
db.collection.aggregate(
{$group : { _id : '$user', count : {$sum : 1}}}
).result
the output for your sample documents is:
"0" : {
"_id" : "2",
"count" : 1
},
"1" : {
"_id" : "3",
"count" : 1
},
"2" : {
"_id" : "1",
"count" : 2
}
Upvotes: 100