Skip to content

Commit ae33bb5

Browse files
committed
fix(things): 修复聚合时间桶匹配与排序
1 parent 5bfa9c6 commit ae33bb5

5 files changed

Lines changed: 92 additions & 7 deletions

File tree

jetlinks-components/tdengine-component/src/test/java/org/jetlinks/community/tdengine/things/TDengineSqlSecurityTest.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,15 +87,16 @@ void shouldMapAggregationAliasByPropertyPartition() {
8787
PropertyAggregation temperatureCount = new PropertyAggregation(
8888
"temperature", "temperatureCount", Aggregation.COUNT);
8989

90+
long timestamp = 1_725_000_000_000L;
9091
TDengineThingDataHelper helper = mock(TDengineThingDataHelper.class);
9192
when(helper.query(anyString())).thenReturn(Flux.just(
92-
TimeSeriesData.of(0, Map.of(
93+
TimeSeriesData.of(timestamp, Map.of(
9394
"property", "temperature",
9495
"__agg_0", 20D,
9596
"__agg_1", 20D,
9697
"__agg_2", 2L
9798
)),
98-
TimeSeriesData.of(0, Map.of(
99+
TimeSeriesData.of(timestamp, Map.of(
99100
"property", "humidity",
100101
"__agg_0", 80D,
101102
"__agg_1", 80D,

jetlinks-components/things-component/src/main/java/org/jetlinks/community/things/data/ThingsDataUtils.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
*/
1616
package org.jetlinks.community.things.data;
1717

18-
import org.jetlinks.community.timeseries.utils.TimeSeriesUtils;
1918
import org.jetlinks.community.Interval;
2019
import org.jetlinks.community.timeseries.utils.TimeSeriesUtils;
2120
import org.joda.time.DateTime;
@@ -52,13 +51,13 @@ public static NavigableMap<Long, Map<String, Object>> prepareAggregationData(Agg
5251
public static NavigableMap<Long, Map<String, Object>> prepareAggregationData(AggregationRequest request,
5352
BiFunction<Long, Interval, Long> timeTruncate,
5453
PropertyAggregation... properties) {
55-
NavigableMap<Long, Map<String, Object>> data = new TreeMap<>(Comparator.comparingLong(l -> -l));
54+
NavigableMap<Long, Map<String, Object>> data = new TreeMap<>();
5655
Map<String, Object> valueMap = new HashMap<>();
5756
for (PropertyAggregation property : properties) {
5857
valueMap.put(property.getAlias(), property.getDefaultValue());
5958
}
6059
if (request.getInterval() == null) {
61-
data.put(0L,valueMap);
60+
data.put(0L, valueMap);
6261
return data;
6362
}
6463
DateTimeFormatter formatter = DateTimeFormat.forPattern(request.getFormat());
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/*
2+
* Copyright 2026 JetLinks https://www.jetlinks.cn
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.jetlinks.community.things.data;
17+
18+
import org.jetlinks.community.Interval;
19+
import org.jetlinks.community.timeseries.query.Aggregation;
20+
import org.junit.jupiter.api.Test;
21+
22+
import java.util.Date;
23+
import java.util.Map;
24+
import java.util.NavigableMap;
25+
26+
import static org.junit.jupiter.api.Assertions.assertEquals;
27+
import static org.junit.jupiter.api.Assertions.assertSame;
28+
29+
class ThingsDataUtilsTest {
30+
31+
private static final PropertyAggregation TEMPERATURE =
32+
new PropertyAggregation("temperature", "temperatureAvg", Aggregation.AVG);
33+
34+
@Test
35+
void shouldMatchNonZeroTimestampWithoutInterval() {
36+
AggregationRequest request = AggregationRequest
37+
.builder()
38+
.interval(null)
39+
.build();
40+
41+
NavigableMap<Long, Map<String, Object>> prepares =
42+
ThingsDataUtils.prepareAggregationData(request, TEMPERATURE);
43+
44+
assertEquals(0L, prepares.firstKey());
45+
assertSame(prepares.get(0L), ThingsDataUtils.findAggregationData(1_725_000_000_000L, prepares));
46+
}
47+
48+
@Test
49+
void shouldMatchRawTimestampToPreviousTimeBucket() {
50+
long from = 1_725_000_000_000L;
51+
AggregationRequest request = AggregationRequest
52+
.builder()
53+
.interval(Interval.ofHours(1))
54+
.format("yyyy-MM-dd HH:mm")
55+
.from(new Date(from))
56+
.to(new Date(from + 2 * 60 * 60 * 1000L))
57+
.build();
58+
59+
NavigableMap<Long, Map<String, Object>> prepares =
60+
ThingsDataUtils.prepareAggregationData(request, (time, interval) -> time, TEMPERATURE);
61+
62+
long firstBucket = prepares.firstKey();
63+
assertSame(
64+
prepares.get(firstBucket),
65+
ThingsDataUtils.findAggregationData(firstBucket + 30 * 60 * 1000L, prepares)
66+
);
67+
}
68+
69+
@Test
70+
void shouldPrepareNaturalOrderAndReadNewestFirst() {
71+
long from = 1_725_000_000_000L;
72+
AggregationRequest request = AggregationRequest
73+
.builder()
74+
.interval(Interval.ofHours(1))
75+
.format("yyyy-MM-dd HH:mm")
76+
.from(new Date(from))
77+
.to(new Date(from + 2 * 60 * 60 * 1000L))
78+
.build();
79+
80+
NavigableMap<Long, Map<String, Object>> prepares =
81+
ThingsDataUtils.prepareAggregationData(request, (time, interval) -> time, TEMPERATURE);
82+
83+
assertEquals(prepares.lastKey(), prepares.descendingMap().firstKey());
84+
}
85+
}

jetlinks-components/timescaledb-component/src/main/java/org/jetlinks/community/timescaledb/thing/TimescaleDBColumnModeQueryOperations.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ static Flux<AggregationData> doAggregation0(DatabaseOperator database,
177177
}
178178
});
179179
})
180-
.thenMany(Flux.fromIterable(prepares.values()))
180+
.thenMany(Flux.fromIterable(prepares.descendingMap().values()))
181181
.map(AggregationData::of)
182182
.take((long) request.getLimit() * context.getProperties().length)
183183
.contextWrite(ctx -> ctx.put(Logger.class, log));

jetlinks-components/timescaledb-component/src/main/java/org/jetlinks/community/timescaledb/thing/TimescaleDBRowModeQueryOperations.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ protected Flux<AggregationData> doAggregation(String metric,
191191
}
192192
});
193193
})
194-
.thenMany(Flux.fromIterable(prepares.values()))
194+
.thenMany(Flux.fromIterable(prepares.descendingMap().values()))
195195
.map(AggregationData::of)
196196
.take((long) request.getLimit() * propertyId.size())
197197
.contextWrite(ctx -> ctx.put(Logger.class, log));

0 commit comments

Comments
 (0)