Node.js Mongoose如何过滤集合数组中amount大于10的产品?
解决Mongoose数组元素过滤问题
你之前用.find({'products.amount': { $gt: 10 }})没达到预期,是因为这个写法只是筛选出包含至少一个符合条件products元素的文档,但不会修改数组内容——数组里还是会保留所有元素,包括amount≤10的。要过滤数组里的元素,得用$filter操作符,下面给两种可行的实现方式:
方法一:使用聚合管道(推荐,适合复杂场景)
聚合管道能分步处理数据,逻辑更清晰:
exports.getProducts = async (req,res) => { try { const result = await Products.aggregate([ // 先筛选出inStock为false的文档 { $match: { inStock: false } }, // 过滤products数组,只保留amount>10的项 { $addFields: { products: { $filter: { input: "$products", as: "item", cond: { $gt: ["$$item.amount", 10] } } } }}, // 移除不需要的字段 { $project: { _id: 0, createdAt: 0, __v: 0 } } ]); if(result.length === 0) { return res.status(400).json({ data: 'No product found' }); } return res.json({ data: result }); } catch(err) { return res.json({ err: err.message }); } }
方法二:在find查询中直接用投影(适合简单场景)
如果逻辑不复杂,也可以直接在find的投影参数里完成过滤:
exports.getProducts = async (req,res) => { try { const result = await Products.find( { inStock: false }, { _id: 0, createdAt: 0, __v: 0, products: { $filter: { input: "$products", as: "item", cond: { $gt: ["$$item.amount", 10] } } } } ).exec(); if(result.length === 0) { return res.status(400).json({ data: 'No product found' }); } return res.json({ data: result }); } catch(err) { return res.json({ err: err.message }); } }
补充说明
- 原代码里的
if(result.err)判断无效,因为find或aggregate返回的结果数组不会带err属性,改用try-catch捕获异步错误更可靠。 - 两种方法都会返回
inStock:false的文档,且每个文档的products数组只保留amount>10的元素。
内容的提问来源于stack exchange,提问作者Otis
相关产品推荐
相关产品推荐

