@@ -59,7 +59,8 @@ export default class RedisHelper {
5959 }
6060
6161 public async getChartDataFromRedis (
62- hours : number , // количество интервалов (часов или дней)
62+ groupingBy : 'hours' | 'days' ,
63+ rangeValue : number ,
6364 timezoneOffset = 0 ,
6465 projectId = '' ,
6566 groupHash = ''
@@ -68,71 +69,84 @@ export default class RedisHelper {
6869 throw new Error ( 'Redis client not connected' ) ;
6970 }
7071
72+ const suffix = groupingBy === 'hours' ? 'hourly' : 'daily' ;
7173 const key = groupHash
72- ? `ts:events:${ groupHash } :hourly `
74+ ? `ts:events:${ groupHash } :${ suffix } `
7375 : projectId
74- ? `ts:events:${ projectId } :hourly`
75- : `ts:events:hourly` ;
76-
77- const now = Date . now ( ) ;
78-
79- // определяем начало выборки
80- const fromDate = new Date ( now ) ;
81- fromDate . setMinutes ( 0 , 0 , 0 ) ;
82- fromDate . setMilliseconds ( fromDate . getMilliseconds ( ) - ( hours * 60 * 60 * 1000 ) ) ;
83- const from = fromDate . getTime ( ) ;
84-
85- let result : [ string , string ] [ ] = [ ] ;
86- try {
87- result = ( await this . redisClient . sendCommand ( [
88- 'TS.RANGE' ,
89- key ,
90- from . toString ( ) ,
91- now . toString ( ) ,
92- ] ) ) as [ string , string ] [ ] | [ ] ;
93- } catch ( err : any ) {
94- if ( err . message . includes ( 'TSDB: the key does not exist' ) ) {
95- console . warn ( `[Redis] Key ${ key } does not exist, returning zeroed data` ) ;
96- result = [ ] ;
76+ ? `ts:events:${ projectId } :${ suffix } `
77+ : `ts:events:${ suffix } ` ;
78+
79+ const now = Date . now ( ) ;
80+
81+ // определяем начало выборки
82+ const fromDate = new Date ( now ) ;
83+ if ( groupingBy === 'hours' ) {
84+ fromDate . setMinutes ( 0 , 0 , 0 ) ;
9785 } else {
98- throw err ;
86+ fromDate . setHours ( 0 , 0 , 0 , 0 ) ;
9987 }
100- }
101-
102- console . log ( groupHash , result )
103-
104- // агрегируем события по интервалу
105- const dataPoints : { [ ts : number ] : number } = { } ;
106- for ( const [ tsStr ] of result ) {
107- const tsMs = Number ( tsStr ) ;
108- const date = new Date ( tsMs ) ;
109-
110- let intervalStart : number ;
111- date . setMinutes ( 0 , 0 , 0 ) ;
112- intervalStart = Date . UTC ( date . getUTCFullYear ( ) , date . getUTCMonth ( ) , date . getUTCDate ( ) , date . getUTCHours ( ) ) ;
113-
114- const intervalWithOffset = intervalStart + timezoneOffset * 60 * 1000 ;
115-
116- dataPoints [ intervalWithOffset ] = ( dataPoints [ intervalWithOffset ] || 0 ) + 1 ;
117- }
118-
119- // заполняем пропущенные интервалы нулями
120- const filled : { timestamp : number ; count : number } [ ] = [ ] ;
121- const nowDate = new Date ( now ) ;
122-
123- for ( let i = 0 ; i < hours ; i ++ ) {
124- const date = new Date ( nowDate ) ;
125-
126- date . setHours ( date . getHours ( ) - i , 0 , 0 , 0 ) ;
127- var intervalStart = Date . UTC ( date . getUTCFullYear ( ) , date . getUTCMonth ( ) , date . getUTCDate ( ) , date . getUTCHours ( ) ) ;
128-
129- const intervalWithOffset = intervalStart + timezoneOffset * 60 * 1000 ;
130- filled . push ( {
131- timestamp : Math . floor ( intervalWithOffset / 1000 ) ,
132- count : dataPoints [ intervalWithOffset ] || 0 ,
133- } ) ;
134- }
135-
136- return filled . sort ( ( a , b ) => a . timestamp - b . timestamp ) ;
88+ fromDate . setMilliseconds ( fromDate . getMilliseconds ( ) - ( groupingBy === 'hours' ? rangeValue * 60 * 60 * 1000 : rangeValue * 24 * 60 * 60 * 1000 ) ) ;
89+ const from = fromDate . getTime ( ) ;
90+
91+ let result : [ string , string ] [ ] = [ ] ;
92+ try {
93+ result = ( await this . redisClient . sendCommand ( [
94+ 'TS.RANGE' ,
95+ key ,
96+ from . toString ( ) ,
97+ now . toString ( ) ,
98+ ] ) ) as [ string , string ] [ ] | [ ] ;
99+ } catch ( err : any ) {
100+ if ( err . message . includes ( 'TSDB: the key does not exist' ) ) {
101+ console . warn ( `[Redis] Key ${ key } does not exist, returning zeroed data` ) ;
102+ result = [ ] ;
103+ } else {
104+ throw err ;
105+ }
106+ }
107+
108+ // агрегируем события по интервалу
109+ const dataPoints : { [ ts : number ] : number } = { } ;
110+ for ( const [ tsStr ] of result ) {
111+ const tsMs = Number ( tsStr ) ;
112+ const date = new Date ( tsMs ) ;
113+
114+ let intervalStart : number ;
115+ if ( groupingBy === 'hours' ) {
116+ date . setMinutes ( 0 , 0 , 0 ) ;
117+ intervalStart = Date . UTC ( date . getUTCFullYear ( ) , date . getUTCMonth ( ) , date . getUTCDate ( ) , date . getUTCHours ( ) ) ;
118+ } else {
119+ date . setHours ( 0 , 0 , 0 , 0 ) ;
120+ intervalStart = Date . UTC ( date . getUTCFullYear ( ) , date . getUTCMonth ( ) , date . getUTCDate ( ) ) ;
121+ }
122+
123+ const intervalWithOffset = intervalStart + timezoneOffset * 60 * 1000 ;
124+ dataPoints [ intervalWithOffset ] = ( dataPoints [ intervalWithOffset ] || 0 ) + 1 ;
125+ }
126+
127+ // заполняем пропущенные интервалы нулями
128+ const filled : { timestamp : number ; count : number } [ ] = [ ] ;
129+ const nowDate = new Date ( now ) ;
130+
131+ for ( let i = 0 ; i < rangeValue ; i ++ ) {
132+ const date = new Date ( nowDate ) ;
133+
134+ if ( groupingBy === 'hours' ) {
135+ date . setHours ( date . getHours ( ) - i , 0 , 0 , 0 ) ;
136+ var intervalStart = Date . UTC ( date . getUTCFullYear ( ) , date . getUTCMonth ( ) , date . getUTCDate ( ) , date . getUTCHours ( ) ) ;
137+ } else {
138+ date . setDate ( date . getDate ( ) - i ) ;
139+ date . setHours ( 0 , 0 , 0 , 0 ) ;
140+ var intervalStart = Date . UTC ( date . getUTCFullYear ( ) , date . getUTCMonth ( ) , date . getUTCDate ( ) ) ;
141+ }
142+
143+ const intervalWithOffset = intervalStart + timezoneOffset * 60 * 1000 ;
144+ filled . push ( {
145+ timestamp : Math . floor ( intervalWithOffset / 1000 ) ,
146+ count : dataPoints [ intervalWithOffset ] || 0 ,
147+ } ) ;
148+ }
149+
150+ return filled . sort ( ( a , b ) => a . timestamp - b . timestamp ) ;
137151 }
138152}
0 commit comments