MongoDB |如何计算对象数组中属性的特定值并按属性分组

时间:2019-11-12 14:08:53

标签: mongodb mongodb-query aggregation-framework

具有包含以下内容的文档:

{ 
    "_id" : ObjectId("5dc027718da295b969e529ae"), 
    "emp_no" : 10001, 
    "gender" : "M", 
    "titles" : [
        {
            "title" : "Senior Engineer", 
            "dept_name" : "Development", 
            "from_date" : "1986-06-26", 
            "to_date" : "9999-01-01"
        },
        {
            "title" : "Staff", 
            "dept_name" : "Human Resources", 
            "from_date" : "1986-06-26", 
            "to_date" : "9999-01-01"
        }
    ]
}

如何计算某个部门中有M个,所以我会得到类似 Development:874505 的结果?
我还有另一个集合,其中包括以下文件:

//one document
{ 
    "_id" : ObjectId("5dc026438da295b969e01893"), 
    "dept_no" : "d005", 
    "dept_name" : "Development", 
    "emp_no" : 10001, 
    "from_date" : "1986-06-26", 
    "to_date" : "9999-01-01"
}

//another document
{ 
    "_id" : ObjectId("5dc026438da295b969e01894"), 
    "dept_no" : "d003", 
    "dept_name" : "Human Resources", 
    "emp_no" : 10001, 
    "from_date" : "1986-06-26", 
    "to_date" : "9999-01-01"
}

也许使用此工具可以使过程更容易?

4 个答案:

答案 0 :(得分:0)

这可以通过使用 $ count 运算符来完成。我鼓励您在这里阅读documentation。另外,如果您以前从未使用过方法{strong> aggregate 的documentation

使用第一个收藏集

db.collection.aggregate([
  {
    $match: {
      "titles.title": "Senior Engineer",
      gender: "M"
    }
  },
  {
    $count: "Human Resources count"
  }
])

输出将是:

 {
    "Human Resources count": x
 }

答案 1 :(得分:0)

这里是一个查询,用于计算性别为“ M”并在某个部门工作的对象的数量。

db.col2.aggregate([
    {
        "$match": { "dept_no": "d005"}
    },
    {
        "$lookup": {
            "from": "col1",
            "localField": "emp_no",
            "foreignField": "emp_no",
            "as": "employees"
        }
    },
    {
        "$replaceRoot": { "newRoot": { "$mergeObjects": "$employees" } }
    },
    {
        "$match": { "gender": "M" }
    }, 
    {
        "$count": "m_count"
    }
])

col2集合具有第二组文档,而col1则是具有问题中第一份文档的那个。

答案 2 :(得分:0)

  

我如何计算某个部门中有多少个M,所以我   会得到类似 Development:874505 的结果吗?

聚合查询:

$unwind获取titles数组中的所有子文档元素。然后我们用genderdept_name来匹配它们。最后,算一下。 $group阶段可确保在相同部门中担任两个职务的员工被计为一个

var deptMatch = "Development";

db.emps.aggregate( [
  { $unwind: "$titles" },
  { $match: { gender: "M", "titles.dept_name": deptMatch } },
  { $group: { _id: "$emp_no" } },
  { $count: deptMatch }
] )

注意:如果有很多文件,建议您在展开阶段之前进行性别匹配。在以下阶段,您将处理较少数量的文档。



[编辑添加]

我使用此示例数据(为简便起见删除了一些字段)来获得以下结果:

{ "Development" : 3 }

集合emps的文档:

{ 
    "_id" : 1, 
    "emp_no" : 10001, 
    "gender" : "M", 
    "titles" : [
        { "title" : "Senior Engineer",  "dept_name" : "Development" },
        { "title" : "Staff", "dept_name" : "Human Resources" }
    ]
},
{ 
    "_id" : 2, 
    "emp_no" : 10002, 
    "gender" : "M", 
    "titles" : [
        { "dept_name" : "Development" }
    ]
},
{ 
    "_id" : 3, 
    "emp_no" : 10009, 
    "gender" : "F", 
    "titles" : [
        { "dept_name" : "Procurement" }
    ]
}
{ 
    "_id" : 4, 
    "emp_no" : 10004, 
    "gender" : "M", 
    "titles" : [
        { "dept_name" : "HR" },
        { "dept_name" : "Procurement" }
    ]
}
{   "_id" : 5, 
    "emp_no" : 10012, 
    "gender" : "M", "titles" : [ 
        { "title" : "Staff", "dept_name" : "Development" }, 
        { "title" : "Senior Staff", "dept_name" : "Development" } 
    ] 
}

答案 3 :(得分:0)

我想尝试一下,它应该适合您的情况-考虑有问题的文件:

db.yourFirstCollectionName.aggregate([{ $match: { gender: 'M', 'titles.dept_name': 'Development' } },
{ $count: 'totalNoOfEmployees' }])

结果:

{
    "totalNoOfEmployees" : 1
}

说明:

聚合$match的第一阶段将获取gender :m和&& titles数组中至少一个具有title.dept_name : 'Development'的对象的所有文档。 $count将使我们获得符合此条件的文档数量,仅简单的输出即可得出员工人数。

以防万一,如果您认为不需要aggregation,请通过随意的.find()进行尝试:

db.yourFirstCollectionName.find({ gender: 'M', 'titles.dept_name': 'Development'}).count()

或更简单的使用.count()

db.yourFirstCollectionName.count({ gender: 'M', 'titles.dept_name': 'Development'})

这两个将产生相同的结果:1