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

MongoDB aggregate按用户分方向统计通话数据结果异常排查

错误原因

原聚合写法的核心问题是分组粒度设置错误:

  • 仅使用userId作为单级分组的键,$addToSet会直接遍历当前分组下的每一条原始通话记录生成对象存入数组,无法实现按通话方向的二次聚合。
  • 写在$addToSet内部的$sum累加器不会按direction维度生效:MongoDB的聚合累加器仅对当前$group阶段指定的分组键维度生效,嵌套在数组操作符内部的累加器不会触发跨同方向记录的统计逻辑,只会取单条记录的对应值,最终就会出现同方向记录重复、数值未累加的问题。
  • 由于每条通话记录的duration值不同,$addToSet也无法识别同direction的重复项做去重。
修正方法

需要通过两级分组实现需求:

  1. 第一级分组使用userId + direction作为联合分组键,先统计出每个用户下每个通话方向的总通话时长、总通话次数
  2. 第二级分组仅使用userId作为分组键,将同用户下不同方向的统计结果通过$push整理为目标数组结构

修正后的完整聚合语句:

db.test.aggregate([
    // 筛选指定公司的通话记录,逻辑与原写法一致
    { $match: { company: "companyName" } },
    // 第一级分组:按用户+通话方向双维度聚合
    {
        $group: {
            _id: {
                userId: "$userId",
                direction: "$direction"
            },
            duration: { $sum: "$duration" },
            amount: { $sum: 1 }
        }
    },
    // 第二级分组:按用户维度合并结果,生成目标数组
    {
        $group: {
            _id: "$_id.userId",
            data: {
                $push: {
                    direction: "$_id.direction",
                    duration: "$duration",
                    amount: "$amount"
                }
            }
        }
    }
])

若需要对最终输出的data数组按指定规则排序,MongoDB 5.2及以上版本可在最后追加$set阶段,使用$sortArray对数组内元素排序;低版本可在两级分组之间增加$sort阶段预先按direction排序,再执行$push即可保证数组顺序。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 00:09:13