You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 04:12:29