Add group() aggregator (#7480)

* Add group() aggregator

Signed-off-by: Julien Pivotto <roidelapluie@inuits.eu>
This commit is contained in:
Julien Pivotto 2020-06-30 16:51:18 +02:00 committed by GitHub
parent 27b1009acd
commit 72425d4e3d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 454 additions and 411 deletions

View file

@ -187,6 +187,7 @@ vector of fewer elements with aggregated values:
* `min` (select minimum over dimensions)
* `max` (select maximum over dimensions)
* `avg` (calculate the average over dimensions)
* `group` (all values in the resulting vector are 1)
* `stddev` (calculate population standard deviation over dimensions)
* `stdvar` (calculate population standard variance over dimensions)
* `count` (count number of elements in the vector)

View file

@ -1978,20 +1978,23 @@ func (ev *evaluator) aggregation(op parser.ItemType, grouping []string, without
if k > inputVecLen {
resultSize = inputVecLen
}
if op == parser.STDVAR || op == parser.STDDEV {
result[groupingKey].value = 0.0
} else if op == parser.TOPK || op == parser.QUANTILE {
switch op {
case parser.STDVAR, parser.STDDEV:
result[groupingKey].value = 0
case parser.TOPK, parser.QUANTILE:
result[groupingKey].heap = make(vectorByValueHeap, 0, resultSize)
heap.Push(&result[groupingKey].heap, &Sample{
Point: Point{V: s.V},
Metric: s.Metric,
})
} else if op == parser.BOTTOMK {
case parser.BOTTOMK:
result[groupingKey].reverseHeap = make(vectorByReverseValueHeap, 0, resultSize)
heap.Push(&result[groupingKey].reverseHeap, &Sample{
Point: Point{V: s.V},
Metric: s.Metric,
})
case parser.GROUP:
result[groupingKey].value = 1
}
continue
}
@ -2004,6 +2007,9 @@ func (ev *evaluator) aggregation(op parser.ItemType, grouping []string, without
group.groupCount++
group.mean += (s.V - group.mean) / float64(group.groupCount)
case parser.GROUP:
// Do nothing. Required to avoid the panic in `default:` below.
case parser.MAX:
if group.value < s.V || math.IsNaN(group.value) {
group.value = s.V

View file

@ -92,6 +92,7 @@ AVG
BOTTOMK
COUNT
COUNT_VALUES
GROUP
MAX
MIN
QUANTILE
@ -535,7 +536,7 @@ metric : metric_identifier label_set
;
metric_identifier: AVG | BOTTOMK | BY | COUNT | COUNT_VALUES | IDENTIFIER | LAND | LOR | LUNLESS | MAX | METRIC_IDENTIFIER | MIN | OFFSET | QUANTILE | STDDEV | STDVAR | SUM | TOPK;
metric_identifier: AVG | BOTTOMK | BY | COUNT | COUNT_VALUES | GROUP | IDENTIFIER | LAND | LOR | LUNLESS | MAX | METRIC_IDENTIFIER | MIN | OFFSET | QUANTILE | STDDEV | STDVAR | SUM | TOPK;
label_set : LEFT_BRACE label_set_list RIGHT_BRACE
{ $$ = labels.New($2...) }
@ -635,10 +636,10 @@ series_value : IDENTIFIER
* Keyword lists.
*/
aggregate_op : AVG | BOTTOMK | COUNT | COUNT_VALUES | MAX | MIN | QUANTILE | STDDEV | STDVAR | SUM | TOPK ;
aggregate_op : AVG | BOTTOMK | COUNT | COUNT_VALUES | GROUP | MAX | MIN | QUANTILE | STDDEV | STDVAR | SUM | TOPK ;
// inside of grouping options label names can be recognized as keywords by the lexer. This is a list of keywords that could also be a label name.
maybe_label : AVG | BOOL | BOTTOMK | BY | COUNT | COUNT_VALUES | GROUP_LEFT | GROUP_RIGHT | IDENTIFIER | IGNORING | LAND | LOR | LUNLESS | MAX | METRIC_IDENTIFIER | MIN | OFFSET | ON | QUANTILE | STDDEV | STDVAR | SUM | TOPK;
maybe_label : AVG | BOOL | BOTTOMK | BY | COUNT | COUNT_VALUES | GROUP | GROUP_LEFT | GROUP_RIGHT | IDENTIFIER | IGNORING | LAND | LOR | LUNLESS | MAX | METRIC_IDENTIFIER | MIN | OFFSET | ON | QUANTILE | STDDEV | STDVAR | SUM | TOPK;
unary_op : ADD | SUB;

File diff suppressed because it is too large Load diff

View file

@ -104,6 +104,7 @@ var key = map[string]ItemType{
"count": COUNT,
"min": MIN,
"max": MAX,
"group": GROUP,
"stddev": STDDEV,
"stdvar": STDVAR,
"topk": TOPK,

View file

@ -287,6 +287,9 @@ var tests = []struct {
}, {
input: `AVG`,
expected: []Item{{AVG, 0, `AVG`}},
}, {
input: `GROUP`,
expected: []Item{{GROUP, 0, `GROUP`}},
}, {
input: `MAX`,
expected: []Item{{MAX, 0, `MAX`}},

View file

@ -298,3 +298,25 @@ eval instant at 1m quantile without(point)((scalar(foo)), data)
{test="two samples"} 0.8
{test="three samples"} 1.6
{test="uneven samples"} 2.8
# Tests for group.
clear
load 10s
data{test="two samples",point="a"} 0
data{test="two samples",point="b"} 1
data{test="three samples",point="a"} 0
data{test="three samples",point="b"} 1
data{test="three samples",point="c"} 2
data{test="uneven samples",point="a"} 0
data{test="uneven samples",point="b"} 1
data{test="uneven samples",point="c"} 4
foo .8
eval instant at 1m group without(point)(data)
{test="two samples"} 1
{test="three samples"} 1
{test="uneven samples"} 1
eval instant at 1m group(foo)
{} 1