Mongoose二次分组查询实现:按用户聚合Contact状态统计
解决方案:调整Mongoose聚合查询以获取预期格式
我来帮你调整聚合查询,让它输出你想要的结构。你的原始查询已经完成了基础的分组统计,但缺少将同一用户的多个状态统计合并为数组的步骤,而且$sum: '$count'需要改成$sum: 1(我们要统计每个状态下的文档数量,每个文档对应1次计数)。下面是完整的聚合管道:
const teams = await Contact.aggregate([ // 第一步:按用户+状态分组,统计每个状态的文档数量 { $group: { _id: { user: '$user', status: '$status' }, count: { $sum: 1 } // 每个匹配的文档计数+1 } }, // 第二步:按用户分组,把该用户的所有状态统计合并成数组 { $group: { _id: '$_id.user', statuses: { // 这里提供两种格式选项,对应你需求里的两种写法: // 选项1:{ status: "xxx", count: n }(你最初示例的格式) // $push: { status: '$_id.status', count: '$count' } // 选项2:{ "xxx": n }(你补充需求里想要的格式) $push: { $arrayToObject: [[ "$_id.status", "$count" ]] } } } }, // 第三步:关联User集合,拉取用户的name和incharge信息 { $lookup: { from: 'users', // 注意:这里要填User模型对应的集合名(Mongoose默认是小写复数,比如User对应users) localField: '_id', foreignField: '_id', as: 'user' } }, // 展开user数组(lookup返回的是数组,需要展开成单个对象) { $unwind: '$user' }, // 第四步:整理输出字段结构 { $project: { name: '$user.name', incharge: '$user.incharge', statuses: 1 // 当前的_id已经是用户的_id,不需要额外修改 } }, // 按负责人、用户名排序 { $sort: { incharge: 1, name: 1 } } ]);
关于statuses里的[Object]显示问题
你看到的[Object]是Node.js控制台的默认简略输出,它不会递归展示嵌套对象。如果要查看完整结构,可以用JSON格式化打印:
console.log(JSON.stringify(teams, null, 2));
如果是在API接口中返回给前端,当你把结果转为JSON响应时,会自动展开所有嵌套对象,前端就能看到完整的statuses数组内容。
小提醒
确认lookup的from参数是否正确:Mongoose默认会把模型名转为小写复数,比如User模型对应的集合是users,你的原始代码里写的是members,如果集合名确实是members可以忽略这条提醒。
内容的提问来源于stack exchange,提问作者Neel
相关产品推荐
相关产品推荐

