Mongoose查询问题:仅返回对象中指定匹配条件的特定值
解决MongoDB嵌套数组查询后返回过滤元素的问题
我懂你现在的困扰——折腾了2-3小时,结果用find()查询出来的文档里,details数组还混着不符合条件的元素对吧?这是MongoDB的默认行为:它只会帮你筛选出包含至少一个符合条件元素的整个文档,但不会自动帮你过滤数组里不匹配的项。下面给你两种针对性的解决方案:
方案1:用$elemMatch投影(适合只需要第一个匹配元素)
如果你的details数组里只会有一个符合条件的元素,直接在find()里加上投影参数就行,修改你db.js里的model.find()部分:
model.find(query, { 'details': { $elemMatch: { branches_name: query['details.branches_name'], movies_name: query['details.movies_name'] } } })
这个投影会让MongoDB只返回details数组中第一个匹配branches_name和movies_name条件的元素,其他不匹配的会被排除。
方案2:用聚合管道(适合返回所有匹配的数组元素)
如果details数组可能有多个符合条件的元素,用聚合管道的$filter能更灵活地保留所有匹配项,把db.js里的方法改成聚合版本:
module.exports.getcinemasbranchesmovies = async(model, query) => { return new Promise((resolve, reject) => { if (!query) { query = {}; } console.log("branches: ", query); // 用聚合管道替代find model.aggregate([ // 第一步:筛选出包含符合条件元素的文档 { $match: query }, // 第二步:过滤details数组,只保留符合条件的元素 { $addFields: { details: { $filter: { input: "$details", as: "item", cond: { $and: [ { $eq: ["$$item.branches_name", query['details.branches_name']] }, { $eq: ["$$item.movies_name", query['details.movies_name']] } ] } } } } } ]) .then(res => { console.log("branches: ", res); resolve(res); }) .catch(err => { reject(err); console.log(err); throw err; }); }); }
代码说明:
$match:先过滤出包含符合条件元素的文档,和你原来的find()作用一致$addFields:替换原有的details字段,用$filter遍历数组,只留下同时满足branches_name和movies_name匹配的元素
额外提醒
你原来的查询条件{'details.branches_name': b_name, 'details.movies_name': m_name}是正确的,它会匹配文档中存在至少一个details元素同时满足两个条件的文档,只是默认不会过滤数组内容,所以上面的两种方案都是在这个基础上,进一步处理数组里的元素。
内容的提问来源于stack exchange,提问作者Quer
相关产品推荐
相关产品推荐

