Home > Mobile >  How to write a mongo query to find the count based on gender field with $accumulator?
How to write a mongo query to find the count based on gender field with $accumulator?

Time:12-16

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" }
      }
   }
])

Mongo Playground

  • Related