如何使用Mongoose的countDocuments方法统计多个匹配值的文档数量
调整方案
你可以根据业务需求选择以下两种实现方式:
方案1:接口直接返回所有三个尺寸的计数结果
这种方式一次请求就能拿到Small/Medium/Large三类尺寸的统计值,适合前端需要同时展示所有尺寸计数的场景。
修改后代码如下:
registerRoute.route("/countDocuments").get(async function (req, res) { try { // 并行查询三类尺寸的计数 const [smallCount, mediumCount, largeCount] = await Promise.all([ Sweatersizes.countDocuments({ sweatersize: "Small" }), Sweatersizes.countDocuments({ sweatersize: "Medium" }), Sweatersizes.countDocuments({ sweatersize: "Large" }) ]); // 以对象形式返回所有计数 res.json({ Small: smallCount, Medium: mediumCount, Large: largeCount }); } catch (err) { res.send(err); } });
调用接口后返回格式示例:
{"Small": 12, "Medium": 35, "Large": 22}
方案2:支持通过查询参数指定要统计的尺寸
这种方式更灵活,可适配单尺寸查询、全尺寸查询两种需求:
- 请求
/countDocuments不带参数时返回所有尺寸计数 - 请求
/countDocuments?sweatersize=Small时只返回对应尺寸的计数
修改后代码如下:
registerRoute.route("/countDocuments").get(async function (req, res) { try { const targetSize = req.query.sweatersize; // 如果传了指定尺寸,直接返回对应计数 if (targetSize) { const count = await Sweatersizes.countDocuments({ sweatersize: targetSize }); return res.json(count); } // 没传参数就返回所有尺寸的计数,聚合查询仅需1次数据库请求性能更高 const allCounts = await Sweatersizes.aggregate([ { $match: { sweatersize: { $in: ["Small", "Medium", "Large"] } } }, { $group: { _id: "$sweatersize", count: { $sum: 1 } } } ]); // 把聚合结果转成方便使用的对象格式,默认补0避免缺失尺寸没有返回值 const result = allCounts.reduce((prev, curr) => { prev[curr._id] = curr.count; return prev; }, { Small: 0, Medium: 0, Large: 0 }); res.json(result); } catch (err) { res.send(err); } });
注意事项
- 如果你的Mongoose版本低于5.0,不支持async/await写法,可以把查询逻辑改成嵌套回调或者引入
util.promisify包装countDocuments方法。 - 数据量较大的场景优先选方案2的聚合查询写法,减少数据库请求次数。
内容的提问来源于stack exchange,提问作者fernon
相关产品推荐
相关产品推荐

