如何让MongoDB聚合管道始终返回恰好一个文档?
解决MongoDB聚合管道无匹配时返回空文档的问题
要让管道始终返回1个文档,即使$match阶段没有匹配到数据,你可以通过以下两种实用方法实现:
方法一:用$unionWith合并默认文档
通过$unionWith将聚合结果与一个包含默认值的管道合并,再通过二次分组确保只返回唯一正确结果:
const agg = [ { '$match': { 'aaa': 'bbb' } }, { '$group': { '_id': '', 'total': { '$sum': '$num' } } }, { '$unionWith': { 'pipeline': [ { '$documents': [{ '_id': '', 'total': 0 }] } ] } }, { '$group': { '_id': '$_id', 'total': { '$max': '$total' } } } ];
如果$match和$group阶段有匹配结果,$unionWith会将真实结果与默认文档合并,二次分组时$max会保留真实的total值;如果没有匹配数据,$unionWith只会保留默认文档,最终返回total: 0的文档。
方法二:直接补全默认值并限制返回数量
先执行原有的匹配和分组逻辑,再通过$unionWith加入默认文档,最后用$limit确保只返回一个文档:
const agg = [ { '$match': { 'aaa': 'bbb' } }, { '$group': { '_id': '', 'total': { '$sum': '$num' } } }, { '$unionWith': { 'pipeline': [ { '$documents': [{ '_id': '', 'total': 0 }] } ] } }, { '$limit': 1 } ];
如果前面的$group有结果,$limit会优先取真实的聚合结果;如果没有匹配数据,就返回$unionWith提供的默认文档。
两种方法都能保证无论是否有匹配数据,管道始终返回一个包含total字段的文档,无匹配时total值为0。
内容的提问来源于stack exchange,提问作者Irina Rapoport
相关产品推荐
相关产品推荐

