Node.js中MongoDB按分组名称聚合求和错误排查
解决MongoDB聚合查询分组统计重复累加的问题
看起来你遇到的核心问题是错误的关联逻辑导致数据被重复匹配,咱们一步步拆解问题并修正:
问题根源
你的聚合流程里,在关联templates集合并展开template.devices之后,没有做「上报数据deviceId与模板中设备deviceId的匹配」。这就导致每一条设备上报记录,都会和模板里的所有设备建立关联,进而错误地关联到多个分组,最终统计时所有数据被重复累加,才出现了两组结果完全相同的情况。另外还有个小笔误:$group阶段里的_id字段写了$groupData.groupName,但实际应该是$group.groupName。
修正后的聚合代码
let templateId = "27127206822"; // Dynamic Collection [err, templateData] = await to(mongoose.connection.db.collection(templateId) .aggregate([ { $lookup:{ from:"templates", localField:"template", foreignField:"templateId", as:"template" } }, { $unwind:"$template" }, { $unwind:"$template.devices" }, // 关键新增:匹配当前上报数据对应的设备,避免一对多错误关联 { $match: { $expr: { $eq: ["$deviceId", "$template.devices.deviceId"] } } }, { $lookup:{ from:"groups", localField:"template.devices.group", foreignField:"_id", as:"group" } }, { $unwind:"$group" }, // 修正字段路径:使用正确的分组名称字段 { $group:{ _id: "$group.groupName", heat:{$sum:"$heat"}, humidity:{$sum:"$humidity"}, count:{$sum:1} } } ]));
修正点说明
- 新增
$match阶段:通过$expr表达式比较上报数据的deviceId和模板中设备的deviceId,确保每条上报记录只关联到它所属的设备,从根源上避免了数据重复匹配。 - 修正
$group的_id字段:将错误的$groupData.groupName改为$group.groupName,因为lookup返回的分组数据存储在$group字段中,展开后直接通过$group.groupName获取分组名称。
验证结果
执行修正后的查询后,就能得到你期望的结果:
[ { "_id": "Flats", "heat": 70, "humidity": 70, "count":2 }, { "_id": "SPool", "heat": 120, "humidity": 80, "count":3 } ]
内容的提问来源于stack exchange,提问作者Aravind
相关产品推荐
相关产品推荐

