MongoDB在$project操作中为不存在字段设置默认值的实现问题
MongoDB $project投影缺失字段为指定默认值实现方案
原写法问题说明
你之前的写法错误点在于没有对refs数组的单个元素做逐一匹配,直接取$$refsB.altName返回的是整个关联结果集的altName数组,用$first只会拿到第一条关联数据的altName,无法和refs数组的每个元素对应。
正确实现代码
完整聚合管道如下:
db.CollectionA.aggregate([ // 关联CollectionB拿到匹配的文档集合 { $lookup: { from: "CollectionB", localField: "refs.id", foreignField: "_id", as: "refsB" } }, // 重构refs数组,合并字段并设置默认值 { $project: { name: 1, refs: { $map: { input: "$refs", as: "currRef", in: { $mergeObjects: [ // 保留原ref的id、text字段 "$$currRef", // 匹配对应的CollectionB文档,合并name等字段 { $first: { $filter: { input: "$refsB", cond: { $eq: ["$$this._id", "$$currRef.id"] } } } }, // 统一处理altName默认值 { altName: { $ifNull: [ { $first: { $filter: { input: "$refsB", cond: { $eq: ["$$this._id", "$$currRef.id"] } } } }.altName, "Unspecified" ] } } ] } } } } }, // 清理临时关联字段 { $unset: "refsB" } ])
核心逻辑说明
- 用
$lookup先一次性关联所有refs对应CollectionB的文档,减少关联开销 - 通过
$map遍历原refs数组,逐个匹配对应的关联文档,保证字段对应关系正确 $mergeObjects按顺序合并对象,最后设置的altName规则会覆盖前面的空值,保证缺失时一定会填充默认值$ifNull判断字段存在性,不存在就返回指定的默认值Unspecified
内容的提问来源于stack exchange,提问作者Vu Le Anh
相关产品推荐
相关产品推荐

