Mongo Group按条件和计数

时间:2016-10-24 09:36:45

标签: mongodb mongodb-query aggregation-framework

我有这样的数据,我想要做的就是通过将员工与性别分组来统计员工。

{
   _id: ObjectId("57fd6b064a8d7733079d1bb9"),
   name: "Alex",
   age: 23,
   position: "Manager",
   employees: [{
       _id: ObjectId("58056e62281b7a73dfdb6887"),
       employee_id: ObjectId("57df832364efef57c3540610"),
       name: "Bob",
       age: 20,
       gender: "Male",
       position: "Distributor"
   }, {
       _id: ObjectId("58049fe7bc82e44583c52a64"),
       employee_id: ObjectId("57df830264efef57c354060d"),
       name: "Cindy",
       age: 19,
       gender: "Female",
       position: "Administrator"
   }, {
       _id: ObjectId("58049fe7bc82e44583c52a64"), 
       employee_id: ObjectId("57df830264efef57c354060d"), 
       name: "Dylan",
       age: 21,
       gender: "Male",
       position: "Engineer"
  }]
}

所以,我想拥有的数据就像这样

{
   _id: ObjectId("57fd6b064a8d7733079d1bb9"),
   name: "Alex",
   age: 23,
   position: "Manager",
   male_employees: 2,
   female_employees: 1,
}

我已经尝试了聚合,但仍然没有接近我想要的东西。 我不知道如何将它们分组并同时使用大小

1 个答案:

答案 0 :(得分:4)

在您的汇总管道中,您不需要对文档进行分组,只需使用单个 $project 管道投影所需的字段,然后您需要使用 $size $filter 组合,无需使用 $unwind 即可根据性别获取员工人数。

等式中的 $filter 部分将根据给定条件过滤掉数组元素,在这种情况下,这将是二元性别值。然后, $size 运算符将返回已过滤数组的长度,从而为您提供员工数量。

让我们看一下这个例子:

var count = function(gender){
    return {
        "$size": {
            "$filter": {
                "input": "$employees",
                "as": "emp",
                "cond": { "$eq": [ "$$emp.gender", gender ] }
            }
        }
    }
};
db.collection.aggregate([
    {
        "$project": {
            "name": 1,
            "age": 1,
            "position": 1,
            "male_employees": count("Male"),
            "female_employees": count("Female")
        }
    }
]);

示例输出

{
    "_id" : ObjectId("57fd6b064a8d7733079d1bb9"),
    "name" : "Alex",
    "age" : 23,
    "position" : "Manager",
    "male_employees" : 2,
    "female_employees" : 1
}