如何在MongoDB中计算各部门平均项目时长(禁用unwind和lookup)
解决方案:MongoDB嵌套数组计算平均项目时长(无需$unwind/$lookup)
核心结论
嵌套项目的ObjectId完全不影响查询,问题出在未对日期字段做差值计算,仅返回了原始日期数组。可以通过聚合管道的数组操作符直接完成计算,无需展开数组。
假设文档结构
假设你的部门集合文档结构如下:
{ "_id": ObjectId("60d21b4667d0d8992e610c85"), "deptName": "前端研发部", "projects": [ { "_id": ObjectId("60d21b8967d0d8992e610c86"), "startDate": ISODate("2024-01-01T00:00:00Z"), "endDate": ISODate("2024-02-15T00:00:00Z") }, { "_id": ObjectId("60d21b9f67d0d8992e610c87"), "startDate": ISODate("2024-03-01T00:00:00Z"), "endDate": ISODate("2024-04-01T00:00:00Z") } ] }
聚合管道实现代码
MongoDB 5.0+(支持$dateDiff)
db.departments.aggregate([ { $project: { deptName: 1, projectCount: { $size: "$projects" }, // 已实现的项目数量统计 avgProjectDurationDays: { $avg: { $map: { input: "$projects", as: "proj", in: { $dateDiff: { startDate: "$$proj.startDate", endDate: "$$proj.endDate", unit: "day" // 可替换为hour/minute/millisecond等单位 } } } } } } }, // 可选:格式化平均时长为更易读的格式 { $project: { deptName: 1, projectCount: 1, avgProjectDuration: { $concat: [ { $toString: { $floor: "$avgProjectDurationDays" } }, "天 ", { $toString: { $floor: { $mod: [{ $multiply: ["$avgProjectDurationDays", 24] }, 24] } } }, "小时" ] } } } ])
MongoDB 5.0以下版本(用$subtract计算差值)
db.departments.aggregate([ { $project: { deptName: 1, projectCount: { $size: "$projects" }, avgProjectDurationDays: { $avg: { $map: { input: "$projects", as: "proj", in: { // 计算天数:毫秒数转天数 $divide: [{ $subtract: ["$$proj.endDate", "$$proj.startDate"] }, 1000 * 60 * 60 * 24] } } } } } } ])
关键逻辑说明
$map:遍历projects数组,对每个项目计算时长(日期差值),生成时长数组$avg:直接接收$map返回的时长数组,计算数组元素的平均值,无需使用$unwind展开数组- 嵌套项目的
_id字段不会干扰计算,我们只操作startDate和endDate字段,完全无需处理ObjectId
内容的提问来源于stack exchange,提问作者Pagai
相关产品推荐
相关产品推荐

