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

MongoDB聚合查询exec内用async/await获取产品总数问题

解决MongoDB聚合查询后total返回Promise对象的问题

问题原因

你看到的totttttt Promise { 4 }是因为Product.find(newobj).countDocuments().exec()返回的是Promise实例,你直接将其赋值给total但没有等待它完成resolve,所以输出的是未完成的Promise对象,而非实际的数字。

解决步骤

  1. 将嵌套的回调逻辑改为async/await形式,确保能等待Promise完成
  2. 修正_id查询条件:直接把聚合结果数组赋值给_id是错误的,需要用$in匹配数组中的文档ID
  3. 用await获取countDocuments和产品查询的实际结果,或用Promise.all并行查询提升性能

修正后的代码(并行查询版本,性能更优)

try {
  // 执行聚合查询
  const aggregates = await Product.aggregate([
    {
      $project: {
        document: "$$ROOT",
        floorAverage: { $floor: { $avg: "$ratings.star" } },
      },
    },
    {
      $match: { $or: [obj1] },
    },
  ]).exec();

  console.log("myagreg ids", aggregates);

  // 提取聚合结果中的产品ID,用$in构建查询条件
  const productIds = aggregates.map(item => item.document._id);
  const starobj = { _id: { $in: productIds } };
  const newobj = { ...starobj, ...myfilterlist };

  // 并行查询总数和分页产品列表,减少等待时间
  const [total, products] = await Promise.all([
    Product.find(newobj).countDocuments().exec(),
    Product.find(newobj)
      .populate("category", "_id name")
      .populate("subs", "_id name")
      .populate("postedBy", "_id name")
      .sort({ [sort]: order, _id: 1 })
      .skip((currentPage - 1) * perPage)
      .limit(perPage)
      .exec()
  ]);

  console.log("totttttt", total);
  res.json({ products, total });
} catch (err) {
  console.log("ERROR", err);
  // 统一处理错误,返回500响应
  res.status(500).json({ error: err.message });
}

关键修改点说明

  • 替换回调为async/await:将原本的嵌套回调改为用try/catch包裹的async逻辑,代码更易读且错误处理更统一
  • 修正_id查询条件:MongoDB中用数组匹配文档ID需要使用$in操作符,因此先从聚合结果中提取document._id组成数组
  • 并行查询:用Promise.all同时发起总数查询和产品列表查询,相比串行等待能显著提升接口响应速度
  • await获取实际值:对所有返回Promise的操作(aggregate().exec()、countDocuments().exec()等)使用await,确保拿到的是实际结果而非Promise对象

内容的提问来源于stack exchange,提问作者Singh Ekas

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 21:43:35