MongoDB聚合如何实现类似MySQL union的车辆多指标统计功能
写法存在的问题
- 聚合管道执行逻辑错误:MongoDB聚合管道是顺序执行的,前一个
$group阶段的输出仅包含_id、Avg、Min、Max4个字段,不存在car_mileage字段,第二个$group阶段无法读取到原始的car_mileage字段值,最终计算结果全部为null。 - 表达式语法错误:聚合运算符参数不需要额外嵌套大括号,字段引用必须加
$前缀,你写的$avg: { "$car_cost" }、$avg: { car_mileage }都是语法错误,单独运行能返回结果属于测试环境做了兼容修正,严格模式下会直接报错。 - 逻辑不匹配:你要实现的是SQL UNION返回两行统计结果的逻辑,连续两次
$group是对前一次的统计结果二次统计,和UNION的逻辑完全无关。
最优实现方式
使用$facet阶段可以在单次聚合流程中并行执行多个独立的聚合子管道,分别计算Cost和Mileage的统计值,再拆解为期望的两行输出即可,代码如下:
db.car_data.aggregate([ { $facet: { // 子管道1:计算成本相关统计 cost_stats: [ { $group: { _id: "Cost", Avg: { $avg: "$car_cost" }, Min: { $min: "$car_cost" }, Max: { $max: "$car_cost" }, Unit: { $first: "Dollars" } } } ], // 子管道2:计算里程相关统计 mileage_stats: [ { $group: { _id: "Mileage", Avg: { $avg: "$car_mileage" }, Min: { $min: "$car_mileage" }, Max: { $max: "$car_mileage" }, Unit: { $first: "Miles" } } } ] } }, // 将两个统计数组合并为一个数组 { $project: { all_stats: { $concatArrays: ["$cost_stats", "$mileage_stats"] } } }, // 拆解为单独的文档输出 { $unwind: "$all_stats" }, // 替换根节点,输出期望格式 { $replaceRoot: { newRoot: "$all_stats" } } ])
该方案仅需要扫描一次集合,性能比执行两次单独的聚合查询高很多,运行后输出完全匹配需求。
内容的提问来源于stack exchange,提问作者cramos24
相关产品推荐
相关产品推荐

