如何在MongoDB中多字段分组并统计不同类型任务的数量
实现方案
你可以使用MongoDB聚合管道实现该统计需求,对应Mongoose查询代码如下:
const result = await Task.aggregate([ // 第一步:将Date类型的completed_at格式化为DD-MM-YYYY字符串,和需求格式对齐 { $project: { owner: 1, type: 1, completed_at: { $dateToString: { format: "%d-%m-%Y", date: "$completed_at" } } } }, // 第二步:按owner + 完成日期双重分组,统计每个分组下三类任务的数量 { $group: { _id: { owner: "$owner", completed_at: "$completed_at" }, A: { $sum: { $cond: [{ $eq: ["$type", "A"] }, 1, 0] } }, B: { $sum: { $cond: [{ $eq: ["$type", "B"] }, 1, 0] } }, C: { $sum: { $cond: [{ $eq: ["$type", "C"] }, 1, 0] } } } }, // 第三步:按owner二次分组,将同个owner的所有日期统计结果合并为数组 { $group: { _id: "$_id.owner", completed_at: { $push: { completed_at: "$_id.completed_at", A: "$A", B: "$B", C: "$C" } } } }, // 第四步:格式化输出字段名,和要求的返回结构对齐 { $project: { _id: 0, owner: "$_id", completed_at: 1 } } ])
特殊说明
你给出的期望返回结果中,owner为abc的completed_at是对象格式,其余是数组格式,属于结构不一致的情况。如果确实需要该效果,可以在上述聚合管道最后新增一个步骤,判断completed_at数组长度是否为1,是就取第一个元素即可:
{ $set: { completed_at: { $cond: { if: { $eq: [{ $size: "$completed_at" }, 1] }, then: { $first: "$completed_at" }, else: "$completed_at" } } } }
内容的提问来源于stack exchange,提问作者Uday Mittal
相关产品推荐
相关产品推荐

