MongoDB(Mongoose)如何仅返回文档中嵌套数组符合指定值的记录
问题原因排查
你原先的写法存在3个问题导致过滤失效:
- _id类型不匹配:MongoDB默认主键
_id为ObjectId类型,直接传入字符串"1234567890"无法匹配到对应文档 - 过滤值类型不匹配:数据中
deleted字段为数值类型,你写的字符串"1"无法命中对应数据 $elemMatch投影有局限性:即使前两个问题修复,$elemMatch也仅会返回数组中第一个匹配的子项,无法返回所有符合deleted=1的元素
正确实现方案
方案1:使用$filter投影运算符(MongoDB 4.4+ 推荐)
该写法可以直接在普通查询的投影阶段完成数组过滤,返回所有符合条件的子项:
const query = chatbotMongoModel.find( // 注意把字符串转成ObjectId类型,如果是Mongoose且开启自动类型转换可省略ObjectId包裹 { _id: mongoose.Types.ObjectId("1234567890") }, { answers: { $filter: { input: "$answers", as: "answer", cond: { $eq: ["$$answer.deleted", 1] } } } } )
方案2:使用聚合管道(兼容所有MongoDB版本)
如果你的MongoDB版本较低,也可以用聚合管道实现:
const query = chatbotMongoModel.aggregate([ // 第一步:匹配指定_id的文档 { $match: { _id: mongoose.Types.ObjectId("1234567890") } }, // 第二步:过滤answers数组 { $project: { answers: { $filter: { input: "$answers", as: "answer", cond: { $eq: ["$$answer.deleted", 1] } } } } } ])
执行后就会仅返回answers数组中deleted=1的所有子项,符合你的需求。
内容的提问来源于stack exchange,提问作者Rafael Spessotto
相关产品推荐
相关产品推荐

