如何将时间序列数据中的 return 列作为数组
How do I return columns in timeseries data as arrays
我正在使用 postgres 和 timescaledb 记录将用于 dashboards/charting 的数据。
我在获取所需数据方面没有任何问题我只是不确定我是否以最有效的方式进行操作。
说我有这个查询
SELECT time, queued_calls, active_calls
FROM call_data
ORDER BY time DESC LIMIT 100;
我的前端接收此数据以绘制图表。
我觉得为每个值重复列名非常低效。
以更有效的方式发送数据,如每一列作为这样的数据数组,会不会更好。
{
time: [...],
queued_calls: [...],
active_calls: [...]
}
我想我的问题是,我是否应该重组我的查询以便列数据以某种方式在数组中,或者这是我应该在服务器上查询之后在将其发送到客户端之前做的事情?
-- 更新 -- 附加信息
我将 Node.js 与 Express 和 Sequelize 一起用作 ORM,但是在这种情况下,我只是通过 Sequelize 执行原始查询。
我在前端使用的图表库也将系列数据作为数组,所以我想一石二鸟。
前端图表数据格式:
xaxis:{
categories: [...time]
}
series:[
{name: "Queued Calls", data: [...queued_calls]},
{name: "Active Calls", data: [...active_calls]}
]
后端代码:
async function getLocationData(locationId) {
return await db.sequelize.query(
'SELECT time, queued_calls, active_calls FROM location_data WHERE location_id = :locationId ORDER BY time DESC LIMIT 100;',
{
replacements: { locationId },
type: QueryTypes.SELECT,
}
);
}
...
app.get('/locationData/:locationId', async (req, res) => {
try {
const { locationId } = req.params;
const results = await getLocationData(parseInt(locationId));
res.send(results);
} catch (e) {
console.log('Error getting data', e);
}
});
如果服务器在发送数据时压缩数据,如果您以您正在考虑的数组结构发送数据,那么它不会对网络层产生太大影响。
如果您使用数组结构,您认为您正在破坏 JSON 的优势之一 - 数据结构。您可能会获得一些速度提升,但如果您想查看一段时间内的活动呼叫,您必须拥有正确的索引 - 并打开索引错误的可能性。
我建议保留数据原样。
也许您正在寻找数组聚合?
让我看看我是否遵循这个想法:
create table call_data (time timestamp, queued_calls integer, active_calls integer);
CREATE TABLE
我跳过了 location_id 只是为了简化这里。
正在插入一些数据:
tsdb=> insert into call_data values ('2021-03-03 01:00', 10, 20);
INSERT 0 1
tsdb=> insert into call_data values ('2021-03-03 02:00', 11, 22);
INSERT 0 1
tsdb=> insert into call_data values ('2021-03-03 03:00', 12, 25);
INSERT 0 1
现在检查数据:
SELECT time, queued_calls, active_calls FROM call_data;
time | queued_calls | active_calls
---------------------+--------------+--------------
2021-03-03 01:00:00 | 10 | 20
2021-03-03 02:00:00 | 11 | 22
2021-03-03 03:00:00 | 12 | 25
(3 rows)
如果您只想获取日期,您将拥有:
SELECT time::date, queued_calls, active_calls FROM call_data;
time | queued_calls | active_calls
------------+--------------+--------------
2021-03-03 | 10 | 20
2021-03-03 | 11 | 22
2021-03-03 | 12 | 25
(3 rows)
但还是没有分组,所以,可以结合array_agg来分组:
SELECT time::date, array_agg(queued_calls), array_agg(active_calls) FROM call_data group by time::date;
time | array_agg | array_agg
------------+------------+------------
2021-03-03 | {10,11,12} | {20,22,25}
我正在使用 postgres 和 timescaledb 记录将用于 dashboards/charting 的数据。
我在获取所需数据方面没有任何问题我只是不确定我是否以最有效的方式进行操作。
说我有这个查询
SELECT time, queued_calls, active_calls
FROM call_data
ORDER BY time DESC LIMIT 100;
我的前端接收此数据以绘制图表。
我觉得为每个值重复列名非常低效。
以更有效的方式发送数据,如每一列作为这样的数据数组,会不会更好。
{
time: [...],
queued_calls: [...],
active_calls: [...]
}
我想我的问题是,我是否应该重组我的查询以便列数据以某种方式在数组中,或者这是我应该在服务器上查询之后在将其发送到客户端之前做的事情?
-- 更新 -- 附加信息
我将 Node.js 与 Express 和 Sequelize 一起用作 ORM,但是在这种情况下,我只是通过 Sequelize 执行原始查询。
我在前端使用的图表库也将系列数据作为数组,所以我想一石二鸟。
前端图表数据格式:
xaxis:{
categories: [...time]
}
series:[
{name: "Queued Calls", data: [...queued_calls]},
{name: "Active Calls", data: [...active_calls]}
]
后端代码:
async function getLocationData(locationId) {
return await db.sequelize.query(
'SELECT time, queued_calls, active_calls FROM location_data WHERE location_id = :locationId ORDER BY time DESC LIMIT 100;',
{
replacements: { locationId },
type: QueryTypes.SELECT,
}
);
}
...
app.get('/locationData/:locationId', async (req, res) => {
try {
const { locationId } = req.params;
const results = await getLocationData(parseInt(locationId));
res.send(results);
} catch (e) {
console.log('Error getting data', e);
}
});
如果服务器在发送数据时压缩数据,如果您以您正在考虑的数组结构发送数据,那么它不会对网络层产生太大影响。
如果您使用数组结构,您认为您正在破坏 JSON 的优势之一 - 数据结构。您可能会获得一些速度提升,但如果您想查看一段时间内的活动呼叫,您必须拥有正确的索引 - 并打开索引错误的可能性。
我建议保留数据原样。
也许您正在寻找数组聚合?
让我看看我是否遵循这个想法:
create table call_data (time timestamp, queued_calls integer, active_calls integer);
CREATE TABLE
我跳过了 location_id 只是为了简化这里。
正在插入一些数据:
tsdb=> insert into call_data values ('2021-03-03 01:00', 10, 20);
INSERT 0 1
tsdb=> insert into call_data values ('2021-03-03 02:00', 11, 22);
INSERT 0 1
tsdb=> insert into call_data values ('2021-03-03 03:00', 12, 25);
INSERT 0 1
现在检查数据:
SELECT time, queued_calls, active_calls FROM call_data;
time | queued_calls | active_calls
---------------------+--------------+--------------
2021-03-03 01:00:00 | 10 | 20
2021-03-03 02:00:00 | 11 | 22
2021-03-03 03:00:00 | 12 | 25
(3 rows)
如果您只想获取日期,您将拥有:
SELECT time::date, queued_calls, active_calls FROM call_data;
time | queued_calls | active_calls
------------+--------------+--------------
2021-03-03 | 10 | 20
2021-03-03 | 11 | 22
2021-03-03 | 12 | 25
(3 rows)
但还是没有分组,所以,可以结合array_agg来分组:
SELECT time::date, array_agg(queued_calls), array_agg(active_calls) FROM call_data group by time::date;
time | array_agg | array_agg
------------+------------+------------
2021-03-03 | {10,11,12} | {20,22,25}