MongoDB按时间段聚合传感器数据求各cod指标平均值实现问题
多传感器数据MongoDB聚合求各指标平均值实现方案
注意:现有数据中
val字段为字符串类型,聚合计算前需先转换为数值类型,否则无法正常执行平均值计算。如果你的time字段存储为ISO格式字符串,将下文$match中的ISODate替换为对应格式的字符串即可。
聚合管道实现逻辑
- 第一步:
$match过滤指定时间范围内的目标数据,可按需增加设备ID等过滤条件 - 第二步:
$unwind拆分value数组,将每个传感器指标拆分为独立文档 - 第三步:
$group按指标编码cod分组,使用$avg计算对应val的平均值 - 第四步(可选):
$project调整输出字段格式,更符合业务使用习惯
完整聚合代码示例
db.collection.aggregate([ // 1. 时间范围过滤,替换以下ISODate为你实际的起止时间 { $match: { time: { $gte: ISODate("2021-09-01T00:00:00.000Z"), $lte: ISODate("2021-09-30T23:59:59.999Z") } // 若需要过滤指定设备,可补充id_machine过滤条件 // id_machine: "60ec5692a1796250f821222" } }, // 2. 拆分value数组 { $unwind: "$value" }, // 3. 按cod分组求平均值 { $group: { _id: "$value.cod", avg_val: { $avg: { // 转换val为数值类型,使用$convert可兼容脏数据避免聚合中断 $convert: { input: "$value.val", to: "double", onError: null, // 转换失败时取值为null,$avg会自动跳过空值不参与统计,可按需调整为0 onNull: null } } } } }, // 4. 调整输出字段 { $project: { _id: 0, cod: "$_id", average_value: "$avg_val" } } ])
优化建议
- 建议将
time字段存储为ISODate类型而非字符串,可大幅提升时间范围过滤的查询效率,同时避免格式不一致导致的过滤错误 - 可对
time、id_machine字段建立联合索引,进一步加快数据过滤速度 - 若单条文档的
value数组中存在重复cod(如示例中两个CO2),聚合时会将所有匹配值纳入计算,符合需求无需额外处理
内容的提问来源于stack exchange,提问作者João Bonança
相关产品推荐
相关产品推荐

