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

如何编写MongoDB aggregate聚合查询实现按用户分组统计通话邮件数据

MongoDB 聚合查询解决方案

你原来编写的聚合语句存在以下核心问题:

  • 连续两次使用$group语法错误,第一次$group仅保留了userId字段,后续阶段无法获取timestamp、type、platform等所需字段
  • 后续的$project和$count完全不符合你要整理分类数据的需求

正确聚合语句

const targetGroupId = "6132a0cb74af9d82df74e918"; // 替换为你要查询的groupId

db.collection.aggregate([
  // 第一阶段:筛选指定groupId的所有数据
  { $match: { groupId: targetGroupId } },
  // 第二阶段:按userId分组,分别收集该用户的call和email记录
  {
    $group: {
      _id: "$userId",
      calls: {
        $push: {
          $cond: {
            if: { $eq: ["$type", "call"] },
            then: { k: "$timestamp", v: { platform: "$platform" } },
            else: "$$REMOVE" // 不符合type的直接排除
          }
        }
      },
      emails: {
        $push: {
          $cond: {
            if: { $eq: ["$type", "email"] },
            then: { k: "$timestamp", v: { platform: "$platform" } },
            else: "$$REMOVE"
          }
        }
      }
    }
  },
  // 第三阶段:将calls和emails的数组合并为以timestamp为键的对象
  {
    $project: {
      _id: 0,
      userId: "$_id",
      calls: { $arrayToObject: "$calls" },
      emails: { $arrayToObject: "$emails" }
    }
  },
  // 第四阶段:把所有用户数据合并到同一个文档,携带groupId信息
  {
    $group: {
      _id: null,
      groupId: { $first: targetGroupId },
      users: { $push: { k: "$userId", v: { calls: "$calls", emails: "$emails" } } }
    }
  },
  // 第五阶段:将用户数组合并为以userId为键的对象,符合你期望的结构
  {
    $project: {
      _id: 0,
      groupId: 1,
      userData: { $arrayToObject: "$users" }
    }
  }
]).exec()

输出结构说明

最终返回的结构如下(修正了你示例中数组用字符串键的语法错误,实际为对象结构):

{
  "groupId": "6132a0cb74af9d82df74e918",
  "userData": {
    "6132a04892559282c40fd29a": {
      "calls": {
        "2021-09-01": { "platform": "yahoo" },
        "2021-09-04": { "platform": "yahoo" }
      },
      "emails": {
        "2021-09-01": { "platform": "google" },
        "2021-09-04": { "platform": "google" }
      }
    },
    "6132a04892559282c40ff2a9": {
      "calls": {
        "2021-09-04": { "platform": "yahoo" }
      },
      "emails": {
        "1632958029720": { "platform": "google" }
      }
    }
  }
}

关键操作符说明

  • $cond:条件判断,用来区分call和email两种类型的记录
  • $$REMOVE:聚合系统变量,不符合条件的字段直接排除,不会进入结果数组
  • $arrayToObject:将[ {k:xxx, v:xxx} ]格式的数组转换为键值对对象,实现以timestamp、userId为键的需求

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 13:21:03