在MongoDB的$cond中访问$map变量的问题及解决方案
问题分析与解决方法
错误原因
你在$cond的if条件里使用了{ "$$interaction.prompt": { $exists: true } },这是查询语法而非聚合表达式语法。$exists是MongoDB的查询操作符,仅能用于查询过滤阶段(比如find()、updateMany()的第一个参数),不能直接嵌入到聚合管道的表达式中,因此MongoDB无法识别该语法,抛出了Unrecognized expression '$$interaction.prompt'的错误。
另外,去掉$cond后会给无prompt字段的元素添加prompts:[null],是因为当文档不存在prompt字段时,$$interaction.prompt会返回null,导致生成的数组为[null],不符合需求。
正确实现方式
方法一:使用$type判断字段是否存在
利用$type操作符,若字段不存在则返回"missing"类型,通过判断类型是否不等于"missing"来确定字段存在:
db.test.updateMany( {}, [{ $set: { interactions: { $map: { input: "$interactions", as: "interaction", in: { $mergeObjects: [ "$$interaction", { $cond: { if: { $ne: [{ $type: "$$interaction.prompt" }, "missing"] }, then: { prompts: ["$$interaction.prompt"] }, else: {} } } ] } } } } }] )
方法二:使用$ifNull判断字段是否存在
$ifNull会在字段不存在时返回指定默认值(这里用null),通过判断返回值是否不等于null来确定字段存在:
db.test.updateMany( {}, [{ $set: { interactions: { $map: { input: "$interactions", as: "interaction", in: { $mergeObjects: [ "$$interaction", { $cond: { if: { $ne: [{ $ifNull: ["$$interaction.prompt", null] }, null] }, then: { prompts: ["$$interaction.prompt"] }, else: {} } } ] } } } } }] )
两种方法都能实现需求:仅给存在prompt字段的数组元素添加prompts数组,无prompt字段的元素保持原样。
内容的提问来源于stack exchange,提问作者Bernie
相关产品推荐
相关产品推荐

