You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 09:39:22