Mongo聚合中$arrayToObject缺失键时如何返回空对象?
解决MongoDB $arrayToObject处理空数组报错的问题
直接说解决方案:在生成供$arrayToObject转换的数组前,加个判断——如果failures是空数组,就传空数组给$arrayToObject,它转空数组会直接返回空对象{},完美避开报错。
给你写个完整的聚合管道示例,适配你的需求(匹配指定ID、保留rules、统计failures各level数量转对象):
db.results.aggregate([ // 第一步:匹配指定ID的文档 {$match: {_id: ObjectId("你的目标ID")}}, // 第二步:处理统计和格式转换 {$project: { rules: 1, // 保留原有的rules属性 levelStats: { $arrayToObject: { // 核心判断:failures为空数组就返回空数组,否则生成k/v结构的统计数组 $cond: [ {$eq: ["$failures", []]}, [], {$map: { input: {$setUnion: ["$failures.level"]}, // 去重得到所有level值 as: "level", in: { k: "$$level", // 把level值作为对象的键 v: {$size: {$filter: { // 统计该level在failures中的数量 input: "$failures", cond: {$eq: ["$$this.level", "$$level"]} }} } } } } ] } } } } ])
原理说明
之前报错是因为failures为空时,用来生成k/v结构的步骤没有输出合法的k/v键值对,$arrayToObject找不到必要的键就报错。现在通过$cond提前拦截空数组的情况,传空数组给$arrayToObject,它处理空数组会直接返回空对象,完全符合你的需求。
如果你的failures字段可能存在null或者缺失的情况,可以把判断条件改成{$or: [{$eq: ["$failures", []]}, {$eq: ["$failures", null]}]},覆盖更多场景。
内容的提问来源于stack exchange,提问作者lmarx
相关产品推荐
相关产品推荐

