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 } } ]
关键改动说明
- 修正
$match阶段的字段名错误:原logType应为type,确保匹配正确的字段 - 替换
$push逻辑:用$sum结合$cond条件判断,当文档类型为Type A时累加1,否则累加0,直接得到Type A的文档总数,无需后续处理数组
这样聚合后就能得到符合需求的结果:唯一用户名数量统计准确,Type A的文档总数不会混入Type B的数据。
内容的提问来源于stack exchange,提问作者TheStranger
相关产品推荐
相关产品推荐

