MongoDB聚合查询exec内用async/await获取产品总数问题
解决MongoDB聚合查询后total返回Promise对象的问题
问题原因
你看到的totttttt Promise { 4 }是因为Product.find(newobj).countDocuments().exec()返回的是Promise实例,你直接将其赋值给total但没有等待它完成resolve,所以输出的是未完成的Promise对象,而非实际的数字。
解决步骤
- 将嵌套的回调逻辑改为
async/await形式,确保能等待Promise完成 - 修正
_id查询条件:直接把聚合结果数组赋值给_id是错误的,需要用$in匹配数组中的文档ID - 用
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
相关产品推荐
相关产品推荐

