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

如何改写MongoDB聚合管道?实现按角色统计用户总数量与活跃数量

MongoDB 按角色与活跃状态生成指定格式的聚合统计

我需要根据用户的role(角色)和isActive(活跃状态)生成聚合统计结果,期望输出格式如下:

{
  "role": {
    "user": { "all": 3, "active": 2 },
    "admin": { "all": 1, "active": 1 },
    "vendor": { "all": 2, "active": 2 }
  }
}

当前使用的聚合查询及返回结果无法满足格式要求,以下是相关信息:

示例文档

{
 "email": "doe@gmail.com",
 "firstName": "doe",
 "lastName": "bghh",
 "phone": "+919016703350",
 "password":"$.5GIV3q9JqzRqY/lP2",
 "status": "verified",
 "role": "admin",
 "isActive": true
}

当前聚合查询

const user = await User.aggregate([
    { $project: { isActive: 1, role: 1 } },
    { $group: { _id: { role: '$role', isActive: '$isActive' }, all: { $sum: 1 } } },
 ])

当前查询结果

{
  "user": [
    {
        "_id": {
            "role": "user",
            "isActive": false
        },
        "all": 1
    },
    {
        "_id": {
            "role": "vendor",
            "isActive": true
        },
        "all": 1
    },
    {
        "_id": {
            "role": "user",
            "isActive": true
        },
        "all": 2
    },
    {
        "_id": {
            "role": "vendor",
            "isActive": false
        },
        "all": 1
    },
    {
        "_id": {
            "role": "admin",
            "isActive": true
        },
        "all": 1
    }
  ]
}

解决方案:调整后的聚合查询语句

const userStats = await User.aggregate([
  // 筛选需要的字段,减少数据处理量
  { $project: { role: 1, isActive: 1 } },
  // 按角色分组,统计总数量和活跃用户数
  {
    $group: {
      _id: "$role",
      all: { $sum: 1 },
      active: { $sum: { $cond: [{ $eq: ["$isActive", true] }, 1, 0] } }
    }
  },
  // 将分组结果整理为键值对数组
  {
    $group: {
      _id: null,
      roles: {
        $push: {
          k: "$_id",
          v: { all: "$all", active: "$active" }
        }
      }
    }
  },
  // 转换为目标格式并替换根文档
  {
    $replaceRoot: {
      newRoot: {
        role: { $arrayToObject: "$roles" }
      }
    }
  }
])

语句说明

  1. $project:仅保留role和isActive字段,避免不必要的数据处理。
  2. 第一个$group:按角色分组,用$sum统计该角色的总用户数;用$cond判断用户是否活跃,累加得到活跃用户数。
  3. 第二个$group:把所有角色的统计结果收集成包含键值对的数组,为后续转换对象做准备。
  4. $replaceRoot:通过$arrayToObject将数组转为键值对对象,最终包装成{ role: {...} }的目标格式。

内容的提问来源于stack exchange,提问作者sunilsalat

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 05:50:11