Skip to content

Commit 27ac168

Browse files
committed
[ES|QL] Support set of submetrics in agg metric double
1 parent 5302589 commit 27ac168

File tree

4 files changed

+206
-22
lines changed

4 files changed

+206
-22
lines changed

x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -791,7 +791,12 @@ public enum Cap {
791791
/**
792792
* Support for aggregate_metric_double type
793793
*/
794-
AGGREGATE_METRIC_DOUBLE(AGGREGATE_METRIC_DOUBLE_FEATURE_FLAG.isEnabled());
794+
AGGREGATE_METRIC_DOUBLE(AGGREGATE_METRIC_DOUBLE_FEATURE_FLAG),
795+
796+
/**
797+
* Support for partial subset of metrics in aggregate_metric_double type
798+
*/
799+
AGGREGATE_METRIC_DOUBLE_PARTIAL_SUBMETRICS(AGGREGATE_METRIC_DOUBLE_FEATURE_FLAG);
795800

796801
private final boolean enabled;
797802

x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/planner/AggregateMapper.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@
4848
import java.util.HashMap;
4949
import java.util.List;
5050
import java.util.Map;
51-
import java.util.Objects;
5251
import java.util.stream.Collectors;
5352
import java.util.stream.Stream;
5453

@@ -200,9 +199,6 @@ private static Stream<AggDef> aggDefs(Class<?> clazz) {
200199
if (clazz.isAssignableFrom(Rate.class)) {
201200
// rate doesn't support non-grouping aggregations
202201
return Stream.of(new AggDef(clazz, type, extra, true));
203-
} else if (Objects.equals(type, "AggregateMetricDouble")) {
204-
// TODO: support grouping aggregations for aggregate metric double
205-
return Stream.of(new AggDef(clazz, type, extra, false));
206202
} else {
207203
return Stream.of(new AggDef(clazz, type, extra, true), new AggDef(clazz, type, extra, false));
208204
}

x-pack/plugin/mapper-aggregate-metric/src/main/java/org/elasticsearch/xpack/aggregatemetric/mapper/AggregateMetricDoubleFieldMapper.java

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -540,9 +540,6 @@ public AllReader reader(LeafReaderContext context) throws IOException {
540540
NumericDocValues sumValues = getNumericDocValues(sumFieldType, context.reader());
541541
NumericDocValues valueCountValues = getNumericDocValues(countFieldType, context.reader());
542542

543-
if (minValues == null || maxValues == null || sumValues == null || valueCountValues == null) {
544-
throw new UnsupportedOperationException("Must have all subfields to use aggregate double metric in ESQL");
545-
}
546543
return new BlockDocValuesReader() {
547544

548545
private int docID = -1;
@@ -576,13 +573,13 @@ private void copyDoubleValuesToBuilder(Docs docs, BlockLoader.DoubleBuilder buil
576573
if (doc < lastDoc) {
577574
throw new IllegalStateException("docs within same block must be in order");
578575
}
579-
if (values.advanceExact(doc)) {
576+
if (values == null || values.advanceExact(doc) == false) {
577+
builder.appendNull();
578+
} else {
580579
double value = NumericUtils.sortableLongToDouble(values.longValue());
581580
lastDoc = doc;
582581
this.docID = doc;
583582
builder.appendDouble(value);
584-
} else {
585-
builder.appendNull();
586583
}
587584
}
588585
}
@@ -595,13 +592,13 @@ private void copyIntValuesToBuilder(Docs docs, BlockLoader.IntBuilder builder, N
595592
if (doc < lastDoc) {
596593
throw new IllegalStateException("docs within same block must be in order");
597594
}
598-
if (values.advanceExact(doc)) {
595+
if (values == null || values.advanceExact(doc) == false) {
596+
builder.appendNull();
597+
} else {
599598
int value = Math.toIntExact(values.longValue());
600599
lastDoc = doc;
601600
this.docID = doc;
602601
builder.appendInt(value);
603-
} else {
604-
builder.appendNull();
605602
}
606603
}
607604
}
@@ -610,10 +607,10 @@ private void copyIntValuesToBuilder(Docs docs, BlockLoader.IntBuilder builder, N
610607
public void read(int docId, StoredFields storedFields, Builder builder) throws IOException {
611608
var blockBuilder = (AggregateMetricDoubleBuilder) builder;
612609
this.docID = docId;
613-
read(docId, blockBuilder);
610+
readSingleRow(docId, blockBuilder);
614611
}
615612

616-
private void read(int docId, AggregateMetricDoubleBuilder builder) throws IOException {
613+
private void readSingleRow(int docId, AggregateMetricDoubleBuilder builder) throws IOException {
617614
if (minValues.advanceExact(docId)) {
618615
builder.min().appendDouble(NumericUtils.sortableLongToDouble(minValues.longValue()));
619616
} else {

x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/esql/40_tsdb.yml

Lines changed: 192 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,6 @@ setup:
8080
time_series_dimension: true
8181
agg_metric:
8282
type: aggregate_metric_double
83-
# TODO: tests with a subset of metrics
8483
metrics: [ min, max, sum, value_count ]
8584
default_metric: max
8685
k8s:
@@ -102,6 +101,80 @@ setup:
102101
- '{"@timestamp": "2021-04-28T18:50:04.467Z", "dim": "A", "agg_metric": {"max": 10, "min": -1, "sum": 20, "value_count": 5}}'
103102
- '{"index": {}}'
104103
- '{"@timestamp": "2021-04-28T18:50:24.467Z", "dim": "B", "agg_metric": {"max": 20, "min": 3, "sum": 50, "value_count": 7}}'
104+
- '{"index": {}}'
105+
- '{"@timestamp": "2021-04-28T18:50:44.467Z", "dim": "B", "agg_metric": {"max": 17, "min": -5, "sum": 33, "value_count": 9}}'
106+
107+
- do:
108+
indices.create:
109+
index: test3
110+
body:
111+
settings:
112+
index:
113+
mode: time_series
114+
routing_path: [ k8s.pod.uid ]
115+
time_series:
116+
start_time: 2021-04-28T00:00:00Z
117+
end_time: 2021-04-29T00:00:00Z
118+
mappings:
119+
properties:
120+
"@timestamp":
121+
type: date
122+
agg_metric:
123+
type: aggregate_metric_double
124+
metrics: [ min, max ]
125+
default_metric: min
126+
k8s:
127+
properties:
128+
pod:
129+
properties:
130+
uid:
131+
type: keyword
132+
time_series_dimension: true
133+
- do:
134+
bulk:
135+
refresh: true
136+
index: test3
137+
body:
138+
- '{"index": {}}'
139+
- '{"@timestamp": "2021-04-28T19:50:04.467Z", "agg_metric": {"max": 1, "min": -3}, "k8s": {"pod": {"uid":"947e4ced-1786-4e53-9e0c-5c447e959507"}}}'
140+
- '{"index": {}}'
141+
- '{"@timestamp": "2021-04-28T19:50:24.467Z", "agg_metric": {"max": 10, "min": 3}, "k8s": {"pod": {"uid":"947e4ced-1786-4e53-9e0c-5c447e959507"}}}'
142+
- '{"index": {}}'
143+
- '{"@timestamp": "2021-04-28T19:50:44.467Z", "agg_metric": {"max": 17, "min": 2}, "k8s": {"pod": {"uid":"df3145b3-0563-4d3b-a0f7-897eb2876ea9"}}}'
144+
145+
- do:
146+
indices.create:
147+
index: test4
148+
body:
149+
settings:
150+
index:
151+
mode: time_series
152+
routing_path: [ k8s.pod.uid ]
153+
time_series:
154+
start_time: 2021-04-28T00:00:00Z
155+
end_time: 2021-04-29T00:00:00Z
156+
mappings:
157+
properties:
158+
"@timestamp":
159+
type: date
160+
agg_metric:
161+
type: aggregate_metric_double
162+
metrics: [ sum, value_count ]
163+
default_metric: sum
164+
k8s:
165+
properties:
166+
pod:
167+
properties:
168+
uid:
169+
type: keyword
170+
time_series_dimension: true
171+
- do:
172+
bulk:
173+
refresh: true
174+
index: test4
175+
body:
176+
- '{"index": {}}'
177+
- '{"@timestamp": "2021-04-28T23:50:04.467Z", "agg_metric": {"sum": 1, "value_count": 10}, "k8s": {"pod": {"uid":"947e4ced-1786-4e53-9e0c-5c447e959507"}}}'
105178

106179
---
107180
load everything:
@@ -226,7 +299,7 @@ from doc with aggregate_metric_double:
226299
- match: {columns.3.type: "ip"}
227300
- match: {columns.4.name: "k8s.pod.network.tx"}
228301
- match: {columns.4.type: "long"}
229-
- length: {values: 2}
302+
- length: {values: 3}
230303

231304
---
232305
stats on aggregate_metric_double:
@@ -255,9 +328,122 @@ stats on aggregate_metric_double:
255328
- match: {columns.3.name: "count(agg_metric)"}
256329
- match: {columns.3.type: "long"}
257330
- match: {values.0.0: 20.0}
331+
- match: {values.0.1: -5.0}
332+
- match: {values.0.2: 103.0}
333+
- match: {values.0.3: 21.0}
334+
335+
---
336+
grouping stats on aggregate_metric_double:
337+
- requires:
338+
test_runner_features: [capabilities]
339+
capabilities:
340+
- method: POST
341+
path: /_query
342+
parameters: []
343+
capabilities: [aggregate_metric_double]
344+
reason: "Support for aggregate_metric_double"
345+
- do:
346+
allowed_warnings_regex:
347+
- "No limit defined, adding default limit of \\[.*\\]"
348+
esql.query:
349+
body:
350+
query: "FROM test2
351+
| STATS max(agg_metric), min(agg_metric), sum(agg_metric), count(agg_metric) BY dim
352+
| SORT dim"
353+
- length: {values: 2}
354+
- length: {values.0: 5}
355+
- match: {columns.0.name: "max(agg_metric)"}
356+
- match: {columns.0.type: "double"}
357+
- match: {columns.1.name: "min(agg_metric)"}
358+
- match: {columns.1.type: "double"}
359+
- match: {columns.2.name: "sum(agg_metric)"}
360+
- match: {columns.2.type: "double"}
361+
- match: {columns.3.name: "count(agg_metric)"}
362+
- match: {columns.3.type: "long"}
363+
- match: {columns.4.name: "dim"}
364+
- match: {columns.4.type: "keyword"}
365+
- match: {values.0.0: 10.0}
258366
- match: {values.0.1: -1.0}
259-
- match: {values.0.2: 70.0}
260-
- match: {values.0.3: 12.0}
367+
- match: {values.0.2: 20.0}
368+
- match: {values.0.3: 5.0}
369+
- match: {values.0.4: "A"}
370+
- match: {values.1.0: 20.0}
371+
- match: {values.1.1: -5.0}
372+
- match: {values.1.2: 83.0}
373+
- match: {values.1.3: 16.0}
374+
- match: {values.1.4: "B"}
375+
376+
---
377+
stats on aggregate_metric_double with partial submetrics:
378+
- requires:
379+
test_runner_features: [capabilities]
380+
capabilities:
381+
- method: POST
382+
path: /_query
383+
parameters: []
384+
capabilities: [aggregate_metric_double_partial_submetrics]
385+
reason: "Support for partial submetrics in aggregate_metric_double"
386+
- do:
387+
allowed_warnings_regex:
388+
- "No limit defined, adding default limit of \\[.*\\]"
389+
esql.query:
390+
body:
391+
query: 'FROM test3 | STATS max(agg_metric), min(agg_metric), sum(agg_metric), count(agg_metric) BY k8s.pod.uid | SORT k8s.pod.uid'
392+
393+
- length: {values: 2}
394+
- length: {values.0: 5}
395+
- match: {columns.0.name: "max(agg_metric)"}
396+
- match: {columns.0.type: "double"}
397+
- match: {columns.1.name: "min(agg_metric)"}
398+
- match: {columns.1.type: "double"}
399+
- match: {columns.2.name: "sum(agg_metric)"}
400+
- match: {columns.2.type: "double"}
401+
- match: {columns.3.name: "count(agg_metric)"}
402+
- match: {columns.3.type: "long"}
403+
- match: {columns.4.name: "k8s.pod.uid"}
404+
- match: {columns.4.type: "keyword"}
405+
- match: {values.0.0: 10.0}
406+
- match: {values.0.1: -3.0}
407+
- match: {values.0.2: null}
408+
- match: {values.0.3: null}
409+
- match: {values.0.4: "947e4ced-1786-4e53-9e0c-5c447e959507"}
410+
- match: {values.1.0: 17.0}
411+
- match: {values.1.1: 2.0}
412+
- match: {values.1.2: null}
413+
- match: {values.1.3: null}
414+
- match: {values.1.4: "df3145b3-0563-4d3b-a0f7-897eb2876ea9"}
415+
416+
---
417+
stats on aggregate_metric_double missing min and max:
418+
- requires:
419+
test_runner_features: [ capabilities ]
420+
capabilities:
421+
- method: POST
422+
path: /_query
423+
parameters: [ ]
424+
capabilities: [ aggregate_metric_double_partial_submetrics ]
425+
reason: "Support for partial submetrics in aggregate_metric_double"
426+
- do:
427+
allowed_warnings_regex:
428+
- "No limit defined, adding default limit of \\[.*\\]"
429+
esql.query:
430+
body:
431+
query: 'FROM test4 | STATS max(agg_metric), min(agg_metric), sum(agg_metric), count(agg_metric)'
432+
433+
- length: {values: 1}
434+
- length: {values.0: 4}
435+
- match: {columns.0.name: "max(agg_metric)"}
436+
- match: {columns.0.type: "double"}
437+
- match: {columns.1.name: "min(agg_metric)"}
438+
- match: {columns.1.type: "double"}
439+
- match: {columns.2.name: "sum(agg_metric)"}
440+
- match: {columns.2.type: "double"}
441+
- match: {columns.3.name: "count(agg_metric)"}
442+
- match: {columns.3.type: "long"}
443+
- match: {values.0.0: null}
444+
- match: {values.0.1: null}
445+
- match: {values.0.2: 1.0}
446+
- match: {values.0.3: 10}
261447

262448
---
263449
from index pattern unsupported counter:
@@ -294,7 +480,7 @@ from index pattern unsupported counter:
294480
- match: {columns.7.type: "keyword"}
295481
- match: {columns.8.name: "metricset"}
296482
- match: {columns.8.type: "keyword"}
297-
- length: {values: 10}
483+
- length: {values: 15}
298484

299485
---
300486
from index pattern explicit counter use:
@@ -315,7 +501,7 @@ from index pattern explicit counter use:
315501
query: 'FROM test* | keep *.tx'
316502
- match: {columns.0.name: "k8s.pod.network.tx"}
317503
- match: {columns.0.type: "unsupported"}
318-
- length: {values: 10}
504+
- length: {values: 15}
319505

320506
---
321507
_source:

0 commit comments

Comments
 (0)