如何将MongoDB时序数据按传感器ID聚合为数组形式?
MongoDB时序数据聚合:按传感器分组整理温湿度数组
你可以通过$group配合$cond、$push以及$filter来实现需求,以下是完整的聚合管道:
兼容MongoDB 4.2+的方案(推荐)
db.weather.aggregate([ // 按时间排序,保证数组内数据顺序符合时序 { $sort: { timestamp: 1 } }, // 按sensorId分组,分别收集对应类型的数据 { $group: { _id: "$metadata.sensorId", humidityData: { $push: { $cond: [ { $eq: ["$metadata.type", "humidity"] }, "$humpercent", "$$REMOVE" ] } }, tempData: { $push: { $cond: [ { $eq: ["$metadata.type", "temperature"] }, "$temp", "$$REMOVE" ] } } } }, // 重命名字段并清理结构 { $project: { _id: 0, sensorId: "$_id", humidityData: 1, tempData: 1 } } ])
关键步骤说明:
$sort:先按时间戳升序排序,确保收集的数组数据是按时间先后排列的,符合时序数据的要求。$group:- 以
metadata.sensorId作为分组标识(_id)。 - 使用
$push配合$cond和$$REMOVE:仅当数据类型匹配时,将对应字段的值加入数组;不匹配的项直接跳过,避免数组中出现null值。
- 以
$project:将分组用的_id重命名为sensorId,并隐藏原_id字段,输出目标格式。
兼容低版本MongoDB(4.2以下)的方案
如果你的MongoDB版本不支持$$REMOVE,可以用$filter过滤数组中的null值:
db.weather.aggregate([ { $sort: { timestamp: 1 } }, { $group: { _id: "$metadata.sensorId", humidityData: { $push: { $cond: [ { $eq: ["$metadata.type", "humidity"] }, "$humpercent", null ] } }, tempData: { $push: { $cond: [ { $eq: ["$metadata.type", "temperature"] }, "$temp", null ] } } } }, { $project: { _id: 0, sensorId: "$_id", humidityData: { $filter: { input: "$humidityData", cond: { $ne: ["$$this", null] } } }, tempData: { $filter: { input: "$tempData", cond: { $ne: ["$$this", null] } } } } } ])
这个方案先收集所有匹配/不匹配的项(不匹配的存为null),再用$filter剔除数组中的null值,最终得到干净的温湿度数据数组。
内容的提问来源于stack exchange,提问作者Azeli
相关产品推荐
相关产品推荐

