如何在MongoDB聚合中计算最大值与最后值的百分比差异?
如何在MongoDB聚合中计算最大值与最后值的百分比差异?
嘿,这问题很常见,我来给你一步步说明怎么实现!
首先,咱们得明确百分比差异的计算公式——通常是**((最大值 - 最后值) / 最后值) * 100**(如果你的需求是基于最后值的相对差异;要是想基于最大值,就把分母换成最大值就行)。在MongoDB聚合里,我们可以用聚合操作符来实现这个计算,具体可以分两步走:
完整的聚合查询代码
db['temperatures'].aggregate([ // 第一步:筛选200分钟内的数据,和你原来的逻辑一致 { $match: { create_date: { $gt: new Date(ISODate().getTime() - 1000 * 60 * 200) } } }, // 第二步:分组获取最大值和最后值 { $group: { _id: "Temp", maxTemp: { $max: "$temp" }, // 把原来的temp重命名为maxTemp更清晰 lastTemp: { $last: "$temp" } } }, // 第三步:计算百分比差异 { $project: { _id: 1, maxTemp: 1, lastTemp: 1, percentageDifference: { $cond: { if: { $eq: ["$lastTemp", 0] }, // 处理分母为0的边界情况,避免报错 then: null, // 或者你可以设置成0、"N/A"之类的,根据需求调整 else: { $multiply: [ { $divide: [{ $subtract: ["$maxTemp", "$lastTemp"] }, "$lastTemp"] }, 100 ] } } } } } ])
关键部分解释
- $group阶段:我把原来的
temp字段重命名为maxTemp,last改成lastTemp,这样后续计算时语义更清晰,避免混淆。 - $project阶段的计算逻辑:
- 先用
$subtract算出最大值和最后值的差值:$maxTemp - $lastTemp - 用
$divide把差值除以最后值,得到相对比例 - 用
$multiply乘以100转换成百分比 - 额外加了
$cond判断lastTemp是否为0,防止出现除以0的错误,你可以根据实际需求调整then的返回值(比如返回0或者字符串提示)
- 先用
如果你想把计算逻辑直接整合到$group阶段里,也是可以的,这样少一个阶段:
db['temperatures'].aggregate([ { $match: { create_date: { $gt: new Date(ISODate().getTime() - 1000 * 60 * 200) } } }, { $group: { _id: "Temp", maxTemp: { $max: "$temp" }, lastTemp: { $last: "$temp" }, percentageDifference: { $cond: { if: { $eq: [{ $last: "$temp" }, 0] }, then: null, else: { $multiply: [ { $divide: [{ $subtract: [{ $max: "$temp" }, { $last: "$temp" }] }, { $last: "$temp" }] }, 100 ] } } } } } ])
不过这种写法重复调用了$last和$max,虽然MongoDB会优化,但分开的$project阶段可读性更好,维护起来也更方便。
内容的提问来源于stack exchange,提问作者Kelvin U
相关产品推荐
相关产品推荐

