首页 > 解决方案 > 在 NodeJS 中格式化 Postgres 查询的输出

问题描述

我正在从 TimescaleDB(一个 Postgres DB 插件)查询大量数据并使用 LTTB 对结果进行下采样。我使用pg进行连接和查询,使用downsample对数据进行下采样。我在 Lambda 和我的 Postgres DB 上运行它在 EC2 实例上。

这是我的代码:

const AWS = require('aws-sdk');
const {Client} = require('pg'); //  Needs the nodePostgres Lambda Layer
const LTTB = require("downsample").LTTB;
const numPointsInDownsampledData = 300;


exports.handler = async (event) => {

let response = {};

console.log(JSON.stringify(event));

const client = new Client();

const deviceId = event.deviceId;
const fromDate = event.fromDate;
const toDate = event.toDate;
const column = event.column;

if (!deviceId) { // if we do not have a device id, just bail.
    return response = {
        statusCode: 400,
        body: "No device Id",
    };
}


try {
    await client.connect();
    let data = await getData(deviceId, fromDate, toDate, client, column);


    console.log(data.length);

    response = {
        count: data.length,
        data: data
    };
} catch (e) {
    response = {
        statusCode: 500,
        result: "Error: " + e
    };
} finally {
    client.end();
}

return response;
};



async function getData(deviceId, fromDate, toDate,client, column) {

const dataQuery = getQuery(deviceId, fromDate, toDate, column);
const queryResult = await client.query(dataQuery);
const data = queryResult.rows;
console.log("Full data length: "+data.length);
if(data.length > 300){
    const formattedData = [];
    data.forEach(function (dataItem) {
        formattedData.push({ x: dataItem.time_stamp, y: getColumn(column, dataItem)});
    });
    return LTTB(formattedData, numPointsInDownsampledData);
}else {
    return data;
}
}

function getColumn(column, dataItem) {
switch (column){
    case "i1":                  return dataItem.i1;
    case "i2":                  return dataItem.i2;
    case "i3":                  return dataItem.i3;
    case "i4":                  return dataItem.i4;
    case "i5":                  return dataItem.i5;
    case "i6":                  return dataItem.i6;
    case "i7":                  return dataItem.i7;
    case "i8":                  return dataItem.i8;
    case "mrt":                 return dataItem.mrt;
    case "air_temperature":     return dataItem.air_temperature;
    case "humidity":            return dataItem.humidity;
    case "tvoc":                return dataItem.tvoc;
    case "co2":                 return dataItem.co2;
    case "sitting_mrt":         return dataItem.sitting_mrt;
    case "standing_mrt":        return dataItem.standing_mrt;

}
}


function getQuery(deviceId, fromDate, toDate, column) {
return `SELECT time_stamp,${column}  FROM sensor_data_v2 WHERE device_id = '${deviceId}' and 
                                        time_stamp between '${fromDate}' and '${toDate}';`;
 }

采样包需要对象的输入数组,其格式如下:

{ x: new Date(), y: 152.2 };

所以,我必须遍历查询结果并格式化数据,这样下采样才会满意。可以想象,遍历大量数据可能需要一段时间,结果中可能有 3 到 5 百万行。

问题:

  1. 有什么方法可以将查询结果格式化为下采样会满意的格式。未附加到pg包,如果它具有我需要的功能,很乐意使用另一个。
  2. 有一个更好的方法吗?

标签: node.jspostgresqlamazon-web-servicesaws-lambdatimescaledb

解决方案


推荐阅读