MongoDB聚合管道能否对同一字段执行不同$match操作并在同一输出结果中展示?
嘿,我明白你的问题了——想要在同一个聚合结果里同时统计2020和2021年的价格总和,又不能修改集合结构对吧?你提到的$facet确实是解决这类并行统计需求的好工具,另外还有一种更简洁高效的方法,用$cond在分组阶段直接区分年份,我两种都给你详细讲讲:
方法一:使用$facet并行处理不同年份的统计
$facet的核心作用是让你在一个聚合管道里同时运行多个独立的子管道,每个子管道可以单独做筛选和分组,最后再把结果整合到一起。具体实现步骤如下:
- 用
$facet定义两个子管道,分别处理2020和2021年的数据:- 每个子管道先通过
$match用正则筛选对应年份的书籍 - 然后
$group按REF分组计算该年份的价格总和
- 每个子管道先通过
- 把两个子管道的结果合并,按
REF将同分类的两年统计结果整合到同一个文档中
完整的聚合管道代码:
db.books.aggregate([ { $facet: { year2020: [ { $match: { bname: /2020/ } }, { $group: { _id: "$REF", PriceSum2020: { $sum: "$PRICE" } } } ], year2021: [ { $match: { bname: /2021/ } }, { $group: { _id: "$REF", PriceSum2021: { $sum: "$PRICE" } } } ] } }, { $unwind: "$year2020" }, { $unwind: "$year2021" }, { $match: { $expr: { $eq: ["$year2020._id", "$year2021._id"] } } }, { $project: { _id: 0, REF: "$year2020._id", PriceSum2020: "$year2020.PriceSum2020", PriceSum2021: "$year2021.PriceSum2021" } } ])
步骤解释:
$facet会生成包含year2020和year2021两个数组的文档,每个数组里是对应年份的分组统计结果$unwind把数组拆分成单个文档,方便后续按REF匹配合并$match确保我们只合并同一REF下的两年数据$project整理成你需要的输出格式,去掉默认的_id字段
方法二:使用$cond在分组阶段直接区分年份(更推荐)
这个方法不需要拆分多个子管道,直接在$group阶段通过$cond条件判断书籍名称里的年份,分别累加对应年份的价格总和,代码更简洁,执行效率也更高(只需要一次分组操作):
db.books.aggregate([ { $group: { _id: "$REF", PriceSum2020: { $sum: { $cond: [ { $regexMatch: { input: "$bname", regex: /2020/ } }, "$PRICE", 0 ] } }, PriceSum2021: { $sum: { $cond: [ { $regexMatch: { input: "$bname", regex: /2021/ } }, "$PRICE", 0 ] } } } }, { $project: { _id: 0, REF: "$_id", PriceSum2020: 1, PriceSum2021: 1 } } ])
步骤解释:
$regexMatch用来判断bname是否包含目标年份的正则表达式$cond做条件判断:如果匹配到对应年份,就累加当前文档的PRICE,否则加0(不影响总和)- 最后
$project调整输出格式,把_id字段重命名为REF,去掉默认的_id
这个方法直接就能输出你想要的结果,步骤更少,性能更优,非常适合你的需求!
内容的提问来源于stack exchange,提问作者Aziz Hassine
相关产品推荐
相关产品推荐

