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

MongoDB按周分组:统计指定类型文档数与唯一用户名

MongoDB 聚合查询优化:精准统计Type A文档数量

示例文档

{
    timestamp: ISODate("2022-11-04T08:58:03.303+00:00"),
    name: "Brian",
    username: "B2022@mail.com",
    type: "Type A"
}

{
    timestamp: ISODate("2022-11-04T09:20:13.564+00:00"),
    name: "Brian",
    username: "B2022@mail.com",
    type: "Type A"
}

{
    timestamp: ISODate("2022-11-04T13:12:25.024+00:00"),
    name: "Anna",
    username: "Anna@something.com",
    type: "Type A"
}

{
    timestamp: ISODate("2022-11-04T05:32:58.834+00:00"),
    name: "Max",
    username: "Max@somethingelse.com",
    type: "Type B"
}

{
    timestamp: ISODate("2022-11-04T03:34:23.011+00:00"),
    name: "Jan",
    username: "Jan@somethingelse.com",
    type: "Type c"
}

需求说明

数据用于时间线图表,已通过$densify和$fill生成周数据桶,需要按周分组实现:

  • 统计Type A和Type B的唯一用户名数量
  • 统计Type A类型的文档总数
    期望输出示例:
{
    timestamp: ISODate("2022-10-30T23:00:00.000+00:00"),
    usernameCount: 3,
    typeAOccurencies: 3
}

尝试过的聚合流程

[
    {
        $match: {
            'logType': {  
                $in: [ 'Type A', 'Type B' ] 
            }
        }
    },
    {
        $group: {
            _id: {
                bins: {
                    $dateTrunc: {
                        date: '$timestamp',
                        unit: 'week',
                        binSize: 1,
                        timezone: 'Europe/Paris',
                        startOfWeek: 'monday'
                    }
                }
            },
            usernameCount: {
                $addToSet: '$username'
            },
            typeAOccurencies: {
                $push: '$type'
            },
        }
    }, 
    {
        $project: {
            _id: 0,
            timestamp: '$_id.bins',
            usernameCount: {
                $size: '$usernameCount'
            },
            typeAOccurencies: {
                $size: '$typeAOccurencies'
            }
        }
    }
]

当前问题

typeAOccurencies数组会混入Type B类型的数据,无法精准统计Type A的文档总数。

解决方案

在$group阶段使用$sum配合条件判断替代$push,直接统计符合Type A的文档数量:

[
    {
        $match: {
            'type': {
                $in: [ 'Type A', 'Type B' ] 
            }
        }
    },
    {
        $group: {
            _id: {
                bins: {
                    $dateTrunc: {
                        date: '$timestamp',
                        unit: 'week',
                        binSize: 1,
                        timezone: 'Europe/Paris',
                        startOfWeek: 'monday'
                    }
                }
            },
            usernameCount: {
                $addToSet: '$username'
            },
            // 仅统计Type A类型的文档数
            typeAOccurencies: {
                $sum: {
                    $cond: {
                        if: { $eq: [ '$type', 'Type A' ] },
                        then: 1,
                        else: 0
                    }
                }
            }
        }
    }, 
    {
        $project: {
            _id: 0,
            timestamp: '$_id.bins',
            usernameCount: { $size: '$usernameCount' },
            typeAOccurencies: 1
        }
    }
]

关键改动说明

  1. 修正$match阶段的字段名错误:原logType应为type,确保匹配正确的字段
  2. 替换$push逻辑:用$sum结合$cond条件判断,当文档类型为Type A时累加1,否则累加0,直接得到Type A的文档总数,无需后续处理数组

这样聚合后就能得到符合需求的结果:唯一用户名数量统计准确,Type A的文档总数不会混入Type B的数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 00:15:30