I have timeseries database using TimeScaleDB extension on Postgres for managing the OHLCV values of different resolutions on the tick data.
Aggregation, continues aggregation, materialized view are all working fine. As part of optimization, I need to extract the data from materialized view in my standard POJO in order to avoid looping just to map the result to my response object.
Without this, I have to loop through thousands of results to my response object, which is taking more time and also not good performance during peak traffic times.
My Response Object :
@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
public class TVHistoryDataResponse {
private String s;
private String errmsg;
private List<Long> t;
private List<BigDecimal> o;
private List<BigDecimal> h;
private List<BigDecimal> l;
private List<BigDecimal> c;
private List<BigDecimal> v;
public TVHistoryDataResponse(){
this.c = new ArrayList<>();
this.o = new ArrayList<>();
this.h = new ArrayList<>();
this.l = new ArrayList<>();
this.v = new ArrayList<>();
this.t = new ArrayList<>();
}
Output required:
{
"s":"ok",
"t":[1666447200,1666461600,1666476000,1666490400],
"o":[19214.2,19223.8,19175.0,19195.1],
"h":[19231.3,19236.8,19217.1,19211.1],
"l":[19200.0,19122.0,19164.1,19155.0],
"c":[19223.7,19175.1,19195.2,19188.9],
"v":[5921.40400000014,38568.243999996805,19393.156000002222,18732.651000003843]
}
View Name: one_minute
View Structure :
day | market | high | open | close | low | volume
"2022-10-22 13:35:00+05:30" "BTCUSDT" 19166.5 19166.4 19165 19165 41.954999999999984
"2022-10-22 13:36:00+05:30" "BTCUSDT" 19165.1 19165.1 19162.7 19162.7 13.671999999999999
"2022-10-22 14:18:00+05:30" "BTCUSDT" 19149.6 19149.6 19149.6 19149.5 5.623999999999998
"2022-10-22 14:19:00+05:30" "BTCUSDT" 19149.6 19149.6 19149.5 19149.5 26.797000000000004
Query I have tried :
@Query(nativeQuery = true,
value = "SELECT \n" +
"array_agg(extract(epoch from day))as t,\n" +
"array_agg(open)as o,\n" +
"array_agg(high)as h,\n" +
"array_agg(low)as l,\n" +
"array_agg(close)as c,\n" +
"array_agg(volume)as v FROM one_minute WHERE market=:market AND day>=:start AND day <=:end group BY day ORDER BY day ASC limit 1000;")
Optional<TVHistoryDataResponse> getAggregatedResponse(
@Param(value = "market")String market,
@Param(value = "start")ZonedDateTime start,
@Param(value = "end")ZonedDateTime end);
Method that calls this Query :
public TVHistoryDataResponse fetchHistoryData(Market market, long from, long to, String r) {
TVHistoryDataResponse tvHistoryDataResponse = new TVHistoryDataResponse();
DateTimeFormatter responseFormatter=DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.S");
ZonedDateTime startTime=ZonedDateTime.ofInstant(Instant.ofEpochSecond(from), ZoneOffset.systemDefault());
ZonedDateTime endTime=ZonedDateTime.ofInstant(Instant.ofEpochSecond(to), ZoneOffset.systemDefault());
Optional<TVHistoryDataResponse> testResponse=tradingDataRepository.getAggregatedResponse(market.name(), startTime, endTime);
Using same Query directly in PgAdmin :
Error :
Getting Null values