MongoDB聚合$group阶段返回空结果时如何替换为指定默认值
问题原因
当输入到$group阶段的文档数量为0时,哪怕_id设为null,$group也不会生成任何输出文档,所以后续的replaceRoot等阶段没有处理对象,自然无法生效。
解决方案
方案1:使用$facet实现(兼容性最佳,支持MongoDB 3.4及以上版本)
$facet的特性是无论内部子管道是否返回结果,自身始终会返回至少一个文档,我们可以利用这个特性兜底默认值:
[ // 你其他的聚合阶段也可以放在这里,或者放到下面docs的子管道中 { $facet: { docs: [ // 这里放你原来的所有业务筛选、处理阶段,比如$match、$sort等 { $group: { _id: null, count: {$sum: 1}, results: {$push: '$$ROOT'} } } ] } }, { $replaceRoot: { newRoot: { $cond: { if: {$eq: [{$size: "$docs"}, 0]}, then: {count: 0, results: []}, else: {$first: "$docs"} } } } }, // 可选:去掉不需要的_id字段 {$unset: "_id"} ]
方案2:使用$unionWith兜底默认值(适合MongoDB 4.4及以上版本)
如果你的MongoDB版本支持$documents操作符,可以用更简洁的写法:
[ // 你原来的所有聚合阶段,包括筛选、处理逻辑 { $group: { _id: null, count: {$sum: 1}, results: {$push: '$$ROOT'} } }, { $unionWith: { coll: "dummy", // 此处集合名无需真实存在,仅作为占位符 pipeline: [ {$documents: [{count: 0, results: []}]} ] } }, // 按count倒序,真实数据的count≥1,优先级高于默认值 {$sort: {count: -1}}, // 只取第一条结果 {$limit: 1}, // 可选:去掉不需要的_id字段 {$unset: "_id"} ]
内容的提问来源于stack exchange,提问作者Web Jigooli
相关产品推荐
相关产品推荐

