MongoDB如何基于数组子文档存在性实现条件投影取值
MongoDB 覆写字段优先投影实现方案
你可以通过$filter匹配数组内的目标覆写项,配合$ifNull兜底返回原始值实现需求,不需要嵌套复杂的$cond判断,兼容overrides不存在、无匹配覆写项的场景。
适配MongoDB 5.0+版本的写法
db.collection.aggregate([ { $project: { overrideOrOriginal: { $ifNull: [ // 提取匹配到的foo属性的覆写值 { $getField: { field: "value", input: { $first: { $filter: { input: "$overrides", cond: { $eq: ["$$this.property", "foo"] } } } } } }, // 无匹配时兜底返回原始foo值 "$foo" ] } } } ])
逻辑说明
$filter遍历overrides数组,筛选所有property为foo的子文档,数组不存在或无匹配时返回空数组$first取筛选结果的第一个子文档,无匹配时返回null$getField提取子文档的value值,无匹配时返回null$ifNull判断前面的取值结果为null时,自动返回原始$foo值
低版本兼容写法(MongoDB <5.0)
如果你的MongoDB版本不支持$getField和$first算子,可以用$arrayElemAt和$let替换:
db.collection.aggregate([ { $project: { overrideOrOriginal: { $ifNull: [ { $let: { vars: { matchOverride: { $arrayElemAt: [ { $filter: { input: "$overrides", cond: { $eq: ["$$this.property", "foo"] } } }, 0 ] } }, in: "$$matchOverride.value" } }, "$foo" ] } } } ])
两种写法都可以达到预期效果:示例数据会返回'foo override',无匹配覆写时返回'original foo'。
内容的提问来源于stack exchange,提问作者user2402616
相关产品推荐
相关产品推荐

