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

如何提交编号数组查询MongoDB集合,单次请求返回目标文档对象数组?

问题分析

原代码的核心问题是异步map不会等待内部的Promise完成,purchases.map(async ...)会立刻返回一个Promise数组,但代码没有等待这些Promise执行完毕就直接返回了响应,导致返回的purchases还是初始的编号数组,而非查询后的文档对象。另外,直接修改原数组的做法也不够规范。

解决方案

方案1:用Promise.all处理异步查询(兼容原有逻辑)

把map返回的Promise数组用Promise.all包裹,等待所有查询完成后再生成新数组:

const Purchase = require('../models/purchase.model') 

//Get user purchases
const getPurchases = async(req, res) => {
    const purchaseNos = req.body.purchases;
    if (!purchaseNos || purchaseNos.length === 0) {
        return res.json({ status: 'error', purchase: false })
    }

    // 用map生成查询Promise数组,再用Promise.all等待全部完成
    const purchases = await Promise.all(
        purchaseNos.map(async (transNo) => {
            const purchase = await Purchase.findOne({ trans_no: transNo });
            if (!purchase) {
                // 处理不存在的编号,可根据需求返回默认值或跳过
                return null;
            }
            return {
                date: purchase.date,
                total: purchase.total,
                merchant_name: purchase.merchant_name,
                merchant_id: purchase.merchant_id,
                mop: purchase.mop,
                items: purchase.items,
                trans_no: purchase.trans_no
            };
        })
    );

    // 过滤掉null的结果(如果有的话)
    const validPurchases = purchases.filter(item => item !== null);
    return res.json({ 
        status: 'ok', 
        purchases: validPurchases
    });
}

module.exports = { getPurchases }

方案2:用MongoDB的$in操作符单次查询(推荐,效率更高)

直接通过$in条件一次查询所有匹配的文档,避免多次数据库请求,完全符合“单次请求完成”的需求:

const Purchase = require('../models/purchase.model') 

//Get user purchases
const getPurchases = async(req, res) => {
    const purchaseNos = req.body.purchases;
    if (!purchaseNos || purchaseNos.length === 0) {
        return res.json({ status: 'error', purchase: false })
    }

    // 单次查询所有匹配trans_no的文档
    const purchases = await Purchase.find({
        trans_no: { $in: purchaseNos }
    }).select('date total merchant_name merchant_id mop items trans_no');

    // 如果需要保持原数组的顺序(因为find返回的顺序不一定和$in数组一致),可以重新排序
    const orderedPurchases = purchaseNos.map(no => 
        purchases.find(p => p.trans_no === no)
    ).filter(item => item !== undefined);

    return res.json({ 
        status: 'ok', 
        purchases: orderedPurchases
    });
}

module.exports = { getPurchases }

说明:

  • $in操作符会匹配trans_no在purchaseNos数组中的所有文档,一次请求完成查询,比多次findOne效率高得多。
  • select方法用来指定返回的字段,和你手动构造purchaseObj的效果一致,更简洁。
  • 额外做了顺序保持:因为MongoDB返回的文档顺序不一定和$in数组的顺序一致,所以通过原数组重新映射排序,确保结果顺序和输入的编号顺序一致。

内容的提问来源于stack exchange,提问作者GT Thompson

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 00:25:22