如何在MongoDB中对每n条数据执行均值、中位数等基础统计计算
MongoDB按固定条数分段统计实现方案
全量数据每10条分组统计实现
适用于对全表数据无前置分组、直接每10条为一组计算统计指标的场景,基于MongoDB 5.0+支持的$setWindowFields窗口函数实现,聚合语句如下:
db.collection.aggregate([ // 1. 为全量数据生成连续序号,可修改sortBy自定义排序规则,比如按Sample字段排序 { $setWindowFields: { sortBy: { _id: 1 }, output: { serialNum: { $documentNumber: {} } } } }, // 2. 计算分组编号,每10条数据对应同一个groupId { $addFields: { groupId: { $floor: { $divide: [ { $subtract: [ "$serialNum", 1 ] }, 10 ] } } } }, // 3. 按组号分组计算统计指标 { $group: { _id: "$groupId", avgCount: { $avg: "$Count" }, // 5.3及以上版本支持精确中位数,将method改为"exact"即可 medianCount: { $median: { input: "$Count", method: "approximate" } }, // 需计算总体标准差可替换为$stdDevPop stdDevCount: { $stdDevSamp: "$Count" } } }, // 可选:按组号升序输出结果 { $sort: { _id: 1 } } ])
按Name分组后每10条分段统计实现
适用于先按Name字段分组,再对每个Name下的数据单独按10条分段计算指标的场景,聚合语句如下:
db.collection.aggregate([ // 1. 按Name分区,每个分区内单独生成连续序号 { $setWindowFields: { partitionBy: "$Name", sortBy: { _id: 1 }, output: { serialNum: { $documentNumber: {} } } } }, // 2. 每个Name下每10条对应同一个子组ID { $addFields: { subGroupId: { $floor: { $divide: [ { $subtract: [ "$serialNum", 1 ] }, 10 ] } } } }, // 3. 按Name+子组ID双维度分组计算统计指标 { $group: { _id: { name: "$Name", groupId: "$subGroupId" }, avgCount: { $avg: "$Count" }, medianCount: { $median: { input: "$Count", method: "approximate" } }, stdDevCount: { $stdDevSamp: "$Count" } } }, // 可选:按Name、子组ID升序输出结果 { $sort: { "_id.name": 1, "_id.groupId": 1 } } ])
效果验证
以你给出的示例数据测试:Name为a的3条Count值为10、20、10,因为不足10条会被分到同一个子组,计算结果和预期一致:
- 均值≈13.33
- 中位数=10
- 样本标准差≈5.77
内容的提问来源于stack exchange,提问作者Nirvana
相关产品推荐
相关产品推荐

