如何在MongoDB中按员工统计工时总和并获取对应日期列表
按员工统计工时总和并获取日期列表的MongoDB聚合查询方案
问题背景
我拥有一个名为employees的MongoDB集合,示例文档如下:
{ "_id" : ObjectId("62ccaa238a322322211"), "employeeId" : "1234", "date" : ISODate("2022-07-11T12:00:00.000+0000"), "hours" : 15.0, "createdBy" : "user1", "createdDate" : ISODate("2023-02-19T21:54:27.213+0000"), "updatedBy" : "user1", "updatedDate" : ISODate("2023-02-19T21:54:27.213+0000") }, { "_id" : ObjectId("62ccaa238a322388821"), "employeeId" : "1234", "date" : ISODate("2022-07-10T12:00:00.000+0000"), "hours" : 25.0, "createdBy" : "user1", "createdDate" : ISODate("2023-02-19T22:54:27.213+0000"), "updatedBy" : "user1", "updatedDate" : ISODate("2023-02-19T22:54:27.213+0000") }
期望输出
希望按员工统计hours字段的总和,同时获取该员工对应记录的date字段列表,输出格式如下:
{ "employeeId": "1234", "hours": 40, // 两条记录的工时总和 "dates": ["2022-07-11", "2022-07-10"] // date字段的格式化列表 }
当前尝试的查询
我尝试了以下聚合查询,但不知道如何调整以获取employeeId和工时总和:
db.getCollection("employees").aggregate( [ { $match : { $and :[ {"employeeId" : "1234"}, {"date" : { $lte: new ISODate("2023-02-19") }} ]}}, { $group: { "_id": { "$dateToString": { "format": "%Y-%m-%d", "date": "$date" } }, totalAmount: { $sum: "$hours" } } } ] )
调整后的正确查询
要实现需求,需要调整$group的分组依据,并添加日期收集和字段重命名的逻辑,最终查询如下:
db.getCollection("employees").aggregate([ { $match: { employeeId: "1234", date: { $lte: new ISODate("2023-02-19") } } }, { $group: { _id: "$employeeId", totalHours: { $sum: "$hours" }, dates: { $push: { $dateToString: { format: "%Y-%m-%d", date: "$date" } } } } }, { $project: { _id: 0, employeeId: "$_id", hours: "$totalHours", dates: 1 } } ])
关键调整说明
- $match阶段优化:去掉了冗余的
$and,MongoDB会自动将多个条件视为逻辑与关系,简化查询结构。 - $group阶段调整:将分组依据改为
employeeId,确保按员工聚合数据;用$sum累加工时得到总时长;用$push配合$dateToString收集并格式化所有日期到数组中。 - $project阶段格式化输出:重命名字段以匹配期望格式,去掉默认的
_id字段,将分组的_id转为employeeId,totalHours转为hours,保留dates数组。
内容的提问来源于stack exchange,提问作者Tech_Dev
相关产品推荐
相关产品推荐

