Reputation: 483
I am trying to get the count of all the different value of a key in my MongoDB. I am getting the count as well but i am getting it with 2 different objects.
{ "_id" : ObjectId("596f6e95b6a1aa8d363befeb"), produce:"potato","variety" : "abc", "state" : 'PA' }
{ "_id" : ObjectId("596f6e95b6a1aa8d363befec"), produce:"potato", "variety" : "abc", "state" : 'PA' }
{ "_id" : ObjectId("596f6e95b6a1aa8d363befed"), produce:"potato", "variety" : "def", "state" : 'IA' }
{ "_id" : ObjectId("596f6e95b6a1aa8d363befee"), produce:"potato", "variety" : "def", "state" : 'IA' }
{ "_id" : ObjectId("596f6e95b6a1aa8d363befef"), produce:"potato", "variety" : "abc", "state" : 'DA' }
{ "_id" : ObjectId("596f6e95b6a1aa8d363befeg"), produce:"potato", "variety" : "abc", "state" : 'DA' }
{ "_id" : ObjectId("596f6e95b6a1aa8d363befeh"), produce:"potato", "variety" : "def", "state" : 'DA' }
{ "_id" : ObjectId("596f6e95b6a1aa8d363befei"), produce:"potato", "variety" : "abc", "state" : 'IA' }
db.aggregate([
{
$match:{produce: "potato"}
},
{
"$group":{
"_id":{"variety":"$variety","state":"$state"},
"count":{"$sum":1}
}
},
{
"$group":{
"_id":null,
"counts":{
"$push": {"filterkey":"$_id.variety","state":"$_id.state","count":"$count"}
}
}
},
])
Actual Result : - counts
[
{ filterkey: 'abc', state: 'PA', count: 2},
{ filterkey: 'abc', state: 'IA', count: 1},
{ filterkey: 'abc', state: 'DA', count: 2},
{ filterkey: 'def', state: 'IA', count: 2},
{ filterkey: 'def', state: 'DA', count: 1}
]
Expected Result : - counts
[
{ filterkey: 'abc', states:{'PA':2,'IA':1,'DA':2},
{ filterkey: 'def', states:{'IA':2,'DA':1}
]
Is there is some way to get the data like this?
Upvotes: 2
Views: 649
Reputation: 46451
You need to use multilevel $group
ing here. First you need to use $group
with the variety
and state
fields and need to $sum
to get total number of unique document per variety
and state
.
Then second you need to use $group
with the variety
to get the number of unique documents per variety
.
And Finally $arrayToObject
to flatten the states
array.
db.collection.aggregate([
{ "$match": { "produce": "potato" }},
{ "$group": {
"_id": { "variety": "$variety", "state": "$state" },
"count": { "$sum": 1 }
}},
{ "$group": {
"_id": "$_id.variety",
"states": {
"$push": {
"k": "$_id.state",
"v": "$count"
}
}
}},
{ "$addFields": {
"states": {
"$arrayToObject": "$states"
}
}}
])
You can remove stages one by one here and can see what actually happens.
Output
[
{
"_id": "def",
"states": {
"DA": 1,
"IA": 2
}
},
{
"_id": "abc",
"states": {
"DA": 2,
"IA": 1,
"PA": 2
}
}
]
Upvotes: 2