I'm trying to use the $accumulator function to get the count of names based on gender. Below is my code.
db.collection.aggregate([
{
$match:
{ department: "Finance"}
,
},
{
$group :
{
_id : "$department",
count: { $sum: 1 },
data :
{
$accumulator:
{
init: function() {
return { count: 0, maleCount: 0, femaleCount: 0 }
},
accumulate: function(state, gender) {
if (gender === "Male") {
state.maleCount 1;
}
if (type === "Female") {
state.femaleCount 1;
}
state.count 1;
return state;
},
accumulateArgs: ["$user.gender"],
merge: function(state1, state2) {
return {
count: state1.count state2.count,
maleCount: state1.maleCount state2.maleCount,
femaleCount: state1.femaleCount state2.femaleCount
}
},
finalize: function(state) {
return state;
},
lang: "js"
}
}
}
}
])
My data format is similar to the below:
[
{
"_id": 1,
"department": "Finance",
"user": {
"name": "Staff 1",
"gender": "Male",
}
},
{
"_id": 2,
"department": "Finance",
"user": {
"name": "Staff 2",
"gender": "Female",
}
},
{
"_id": 3,
"department": "Finance",
"user": {
"name": "Staff 3",
"gender": "Male",
}
}
]
I'm expecting the output to be the count of all the staff with maleCount and femaleCount. The below:
{
"_id" : "Finance",
"count" : 3,
"data" : {
"count" : 3,
"maleCount" : 2,
"femaleCount" : 1
}
}
I'm not getting the output as desired. Instead, the output I'm getting is something like the below:
{
"_id" : "Finance",
"count" : 3,
"data" : {
"count" : 0.0,
"maleCount" : 0.0,
"femaleCount" : 0.0
}
}
CodePudding user response:
How about this:
db.collection.aggregate([
{
$setWindowFields: {
partitionBy: { department: "$department", gender: "$user.gender" },
output: {
count: { $count: {} }
}
}
},
{
$group: {
_id: "$department",
data: { $addToSet: { k: "$user.gender", v: "$count" } },
count: { $count: {} }
}
},
{
$project: {
_id: 1,
count: 1,
data: { $arrayToObject: "$data" }
}
}
])