获取数据和过滤数据在后端比在前端花费更长的时间



我尽量减少从后端(w/axios get请求)获得的数据负载,将其过滤到一定数量。它是来自不同传感器的数据。我只想要过去24小时的数据,而不是迄今为止测量的数据。这将产生数万个测量值(存储在MongoDB数据库中)。

在服务器端,我尝试了以下代码:
sensorRoutes.get(
'/', 
expressAsyncHandler( async(req, res) => {
const sensorData = await Sensor.find();
if(sensorData){
const length = sensorData.length;
const timeNow = Date.now();
const last24h = timeNow - 86400000; 
for(let i = 0; i < length; i++){
let array = sensorData[i].values.map(item => [ item.value, item.timestamp ]);
let oneDayData = array.filter(item=> item[1] >= last24h);
sensorData[i].values = oneDayData;
}
res.send(sensorData);
}else{
res.status(404).send({message: 'Sensor not found'});
}
})
);

这大大减慢了整个过程。在应用程序的其他地方使用它之前,上面的内容现在是在前端端。在前端执行它不会像在后端执行它那样减慢进程。

我的问题是,我如何在后端做到这一点,以尽量减少前端的计算负载(和内存使用!)。非常感谢您的帮助。

Thank youLawrence Cherone你提供的答案使我找到了正确的方向。事情是,我应该用MongoDB执行过滤动作,而不是在到达的数据上做脚本。这里的解决方案是使用聚合。我收集大于某一特定值的值。在本例中,我将以毫秒为单位创建的测量时间存储在名为timestamp的字段中。

上面的代码变成:


sensorRoutes.get(
'/', 
expressAsyncHandler( async(req, res) => {
const sensorData = await Sensor.aggregate([
{
$addFields: {
values: {
$filter: {
input: "$values",
as: "value",
cond: {
$gte: ["$$value.timestamp", new Date(Date.now() - 24 * 60 * 60 * 1000).getTime()]
}
}
}
}
}
]);
if(sensorData){
res.send(sensorData);
}else{
res.status(404).send({message: 'Sensor not found'});
}
})
);

此处只有这些值以values的格式添加到值数组的请求(聚合)中:[{value: 23, timestamp: 1678738119782}, {value: 22, timestamp: 1678738117721},…那么MongoDB的$filter函数将以数组values作为输入,其中值和时间戳是该数组中的对象。下面的代码检查是否符合条件,即毫秒数是否大于24小时内的毫秒数。如果是,则接受。