如何将MongoDB中y为null的x值单独分组?
解决方案
要实现将无y字段(或y为null)的文档与有y字段的文档分开分组,你需要在分组条件中加入是否存在有效y值的判断,以此区分两类文档。
原始数据
db={ "Test": [ { "x": "a" }, { "x": "a", "y": 1 }, { "x": "a", "y": 2 } ] }
修改后的聚合管道
db.Test.aggregate([ // 按x和是否存在有效y值分组 { "$group": { "_id": { "x": "$x", // 标记当前分组是否包含非null的y值 "hasValidY": { "$ne": ["$y", null] } }, // 收集分组内的y值 "yList": { "$addToSet": "$y" } } }, // 格式化输出结构,生成目标y数组 { "$project": { "_id": "$_id.x", "y": { "$cond": { if: "$_id.hasValidY", // 过滤有有效y值分组中的null值 then: { "$filter": { input: "$yList", cond: { "$ne": ["$$this", null] } } }, // 无有效y值的分组返回空数组 else: [] } } } }, // 调整_id结构为目标格式 { "$replaceRoot": { newRoot: { "_id": { "x": "$_id" }, "y": "$y" } } } ])
输出结果
[ { "_id": { "x": "a" }, "y": [] }, { "_id": { "x": "a" }, "y": [1, 2] } ]
关键说明
- 分组阶段通过
$ne: ["$y", null]区分两类文档:无y字段的文档中$y会被解析为null,因此会被标记为hasValidY: false;有y字段的文档则标记为true。 - 使用
$filter过滤掉有有效y值分组中的null,避免结果数组包含无效值。 - 最后通过
$replaceRoot调整文档结构,匹配你期望的输出格式。
内容的提问来源于stack exchange,提问作者Marc Grue
相关产品推荐
相关产品推荐

