javascript - 使嵌套的 mongodb 查询更快
问题描述
此函数在 getinitialprops 上触发,它等待它在渲染之前完成。有什么方法可以提高速度而不是等待这个长查询完成?
exports.getAppStats = (req, res, next) => {
const startToday = moment(req.query.today).startOf('day');
const endToday = moment(req.query.today).endOf('day');
const startsevenDays = moment(req.query.today).subtract(7, 'd').startOf('day');
const startThirtyDays = moment(req.query.today).subtract(30, 'd').startOf('day');
const startYear = moment(req.query.today).subtract(365, 'd').startOf('day');
const stats = {}
Application.countDocuments({ dateTime: { $gte: startToday, $lte: endToday } })
.then((result) => {
stats.today = result
Application.countDocuments({ dateTime: { $gte: startsevenDays, $lte: endToday } })
.then((result) => {
stats.sevenDays = result
Application.countDocuments({ dateTime: { $gte: startThirtyDays, $lte: endToday } })
.then((result) => {
stats.thirtyDays = result
Application.countDocuments({ dateTime: { $gte: startYear, $lte: endToday } })
.then((result) => {
stats.year = result
return res.json(stats);
}).catch(err => console.log(err))
}).catch(err => console.log(err))
}).catch(err => console.log(err))
}).catch(err => console.log(err))
}
解决方案
在这里,您可以利用该Promise.all()
函数并行运行所有查询,然后等待所有查询完成,如下所示:
exports.getAppStats = (req, res, next) => {
const startToday = moment(req.query.today).startOf('day');
const endToday = moment(req.query.today).endOf('day');
const startsevenDays = moment(req.query.today).subtract(7, 'd').startOf('day');
const startThirtyDays = moment(req.query.today).subtract(30, 'd').startOf('day');
const startYear = moment(req.query.today).subtract(365, 'd').startOf('day');
const stats = {}
// get promises for each query
let today = Application.countDocuments({ dateTime: { $gte: startToday, $lte: endToday } });
let sevenDays = Application.countDocuments({ dateTime: { $gte: startsevenDays, $lte: endToday } });
let thirtyDays = Application.countDocuments({ dateTime: { $gte: startThirtyDays, $lte: endToday } });
let year = Application.countDocuments({ dateTime: { $gte: startYear, $lte: endToday } });
// wait until all promises have been resolved, then set stats & send response
Promise.all([today, sevenDays, thirtyDays, year]).then(([todayData, sevenDaysData, thirtyDaysData, yearData]) => {
stats = {
today: todayData,
sevenDays: sevenDaysData,
thirtyDays: thirtyDaysData,
year: yearData
}
res.status(200).json({data: stats});
}, (err) => {
console.log(err);
// next(err);
// res.status(500).json({ message: "Something went wrong..." });
});
}
或者,您可以使用async/await
关键字来完全避免回调。虽然它需要try/catch
处理错误。老实说,这没有什么区别,这纯粹是偏好。
// note this is now an async function
exports.getAppStats = async (req, res, next) => {
const startToday = moment(req.query.today).startOf('day');
const endToday = moment(req.query.today).endOf('day');
const startsevenDays = moment(req.query.today).subtract(7, 'd').startOf('day');
const startThirtyDays = moment(req.query.today).subtract(30, 'd').startOf('day');
const startYear = moment(req.query.today).subtract(365, 'd').startOf('day');
// get promises for each query
let today = Application.countDocuments({ dateTime: { $gte: startToday, $lte: endToday } });
let sevenDays = Application.countDocuments({ dateTime: { $gte: startsevenDays, $lte: endToday } });
let thirtyDays = Application.countDocuments({ dateTime: { $gte: startThirtyDays, $lte: endToday } });
let year = Application.countDocuments({ dateTime: { $gte: startYear, $lte: endToday } });
try {
// wait until all promises have been resolved, then set stats & send response
// await Promise.all instead of using callbacks
let [todayData, sevenDaysData, thirtyDaysData, yearData] = await Promise.all(
[today, sevenDays, thirtyDays, year]
);
let stats = {
today: todayData,
sevenDays: sevenDaysData,
thirtyDays: thirtyDaysData,
year: yearData
}
res.status(200).json({data: stats});
} catch(err) {
console.log(err);
// next(err);
// res.status(500).json({ message: "Something went wrong..." });
}
}
推荐阅读
- reactjs - 在 React/Typescript 中的父组件和子组件之间传递状态
- jupyter-notebook - 如何在 Jupyter 笔记本中添加 SageMath 9.4 内核
- c# - 从类方法运行时,C# Timer 只运行一次
- ios - 无法运行 build/ios/iphoneos/Runner.app
- azure - 将字符串长日期时间转换为短日期 (MM/DD/YYYY) ADF
- android - Firebase 我应该如何通过 REST API 发送本地化推送通知?
- c++ - c++ opencv Net type with wrong ram allocation?
- r - 如何在散点图中绘制上限和下限?
- javascript - 试图让交易的剩余时间开始/结束时刻
- javascript - 为什么我不能将动画从 AssimpLoader 导出到 GLTFExporter?