I am trying to aggregate data using mongoDb to gather data per user. I have the following query:
DB.collection.aggregate([
{ "$facet": {
"instructions": [
{ $match: { company: ref } },
{ $group: {
_id : '$user._id',
firstName: { $first: "$user.firstName"},
lastName: { $last: "$user.lastName"},
total: { $sum: 1 },
completed: { $sum: {
"$cond": [
{ "$eq": [ "$completed.value", true ] },
1, 0
]}
},
mostPopularProduct: {
$sortByCount: "$productType"
},
mostPopularType: {
$sortByCount: "$instructionType"
}
}},
]
}},
{ "$project": {
"perClient": { "instructions": "$instructions" }
}}
}}
])
I am trying to get the mostPopularProduct
(and mostPopularInstruction
) in my collection from a string field inside all documents that matches the $match
. Basically the product that appears most across all documents. There are a couple of more calculations being done inside the group.
Currently, I am getting the following error: "unknown group operator '$sortByCount'"
. Now I know it is because it is being used inside the group, which it cannot. But I am unsure how to achieve the desired result. I tried using $sum
, but I did not achieve what I wanted. I don't know if I used it incorrectly.
Can someone please point me in the right direction?
EDIT
Okay, so I might have been a bit vague about what I want. Let me clarify a bit.
I have used $sortByCount
before, like this:
"mostPopularProduct": [
{ $match: { company: ref } },
{ $sortByCount: "$productType"}
],
The result I got was:
"mostPopularProduct": [
{
"_id": "car",
"count": 14
}, {
"_id": "house",
"count": 2
}
]
Now, I want to do the exact same thing, but I want it inside of my group, So basically I want to get the following result:
"perClient": {
"instructions": [
{
"_id": "5fd3db7427e9bc610e4daeaa",
"firstName": "firstName",
"lastName": "lastName",
"total": 8,
"completed": 1,
// NOW HERE ARE THE FIELDS I WANT
"mostPopularProduct": [
{
"_id": "car",
"count": 3
}
]
}, // all other clients follow
]
}
This is the required result I am trying to achieve with the $sortByCount, inside of a $group.
Here is an example: https://mongoplayground.net/p/XolUjfDCpxn
Sample Documents:
[
{ userId: 1, productType: "car" },
{ userId: 1, productType: "car" },
{ userId: 1, productType: "bus" },
{ userId: 1, productType: "bus" },
{ userId: 2, productType: "bus" },
{ userId: 2, productType: "bus" }
]
$group
by userId
and productType
and count the sum$group
by only userId
and prepare the array of productType
and countdb.collection.aggregate([
{
"$facet": {
"instructions": [
{
$group: {
_id: {
userId: "$userId",
productType: "$productType"
},
productTypeCount: { $sum: 1 }
}
},
{
$group: {
_id: "$_id.userId",
mostPopularProduct: {
$push: {
_id: "$_id.productType",
count: "$productTypeCount"
}
}
}
}
]
}
}
])