使用Mongoose Find查询产品时仅首个返回数据其余为undefined怎么办
问题描述
我需要用Mongoose查询一组产品,通过传入每个产品的_id调用Find方法,但遍历数组查询时,只能获取第一个产品的数据,其余产品都返回undefined。
我的代码:
const calc = async (details) => { let grandSubtotal = 0; console.log(details); for (let i = 0; i < details.length; i++) { let verifyProduct = await Product.find({ _id: details[i]._id}); console.log(verifyProduct[i].salePrice); // 只显示第一个产品,其余都是undefined // ...其他代码 } }
MongoDB中的产品文档示例:
{ "_id": "628fa841cde1d960c675ee24", "barCode": "0000075053765", "idProduct": "03", "name": "MALBORO ARTESANAL 20", "desc": "PAQUETE 20 CIGARROS", "presentation": "PIECES", "salePrice": 550, "purchasePrice": 526, "stock": 0, "available": true, "img": [], "status": false }
请问如何获取所有传入产品的salePrice信息?
解决方案
错误原因
Product.find()方法返回的是匹配文档的数组,哪怕只匹配一个产品,返回的也是长度为1的数组。你在循环中使用verifyProduct[i].salePrice,当i≥1时,当前查询返回的数组长度只有1,verifyProduct[i]自然是undefined。
修复方案1:单条查询优化
把find()换成findOne(),它直接返回匹配的单个文档(找不到则返回null),不需要取数组索引:
const calc = async (details) => { let grandSubtotal = 0; console.log(details); for (let i = 0; i < details.length; i++) { // 使用findOne代替find,直接获取单个文档 let verifyProduct = await Product.findOne({ _id: details[i]._id}); if (verifyProduct) { // 先判断是否找到产品,避免报错 console.log(verifyProduct.salePrice); grandSubtotal += verifyProduct.salePrice; } else { console.log(`未找到_id为${details[i]._id}的产品`); } } return grandSubtotal; }
如果坚持使用find(),则应该取数组的第0项(同时用可选链避免找不到产品时报错):
console.log(verifyProduct[0]?.salePrice);
修复方案2:批量查询(更高效)
循环多次查询数据库效率极低,推荐用$in操作符一次性查询所有目标产品:
const calc = async (details) => { let grandSubtotal = 0; // 提取所有需要查询的产品_id const productIds = details.map(item => item._id); // 批量查询所有匹配的产品 const products = await Product.find({ _id: { $in: productIds } }); // 遍历查询结果获取售价并计算总价 products.forEach(product => { console.log(product.salePrice); grandSubtotal += product.salePrice; }); // 如果需要对应原details的顺序,可以手动映射匹配 details.forEach(item => { const matchedProduct = products.find(p => p._id.toString() === item._id.toString()); if (matchedProduct) { console.log(`${item._id}的售价:${matchedProduct.salePrice}`); } }); return grandSubtotal; }
这种方式仅需一次数据库请求,性能远优于循环单条查询。
内容的提问来源于stack exchange,提问作者OscarDev
相关产品推荐
相关产品推荐

