Elasticsearch: Support extended stats and percentiles in terms order by (#28910)
Adds support to the terms aggregation for ordering by percentiles and extended stats. Closes #5148 Co-authored-by: Giordano Ricci <grdnricci@gmail.com> Co-authored-by: Marcus Efraimsson <marcus.efraimsson@gmail.com>
This commit is contained in:
co-authored by
Giordano Ricci
Marcus Efraimsson
parent
b32c4f34cd
commit
5088e2044a
@@ -2,6 +2,7 @@ package elasticsearch
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strconv"
|
||||
|
||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||
@@ -240,15 +241,27 @@ func addTermsAgg(aggBuilder es.AggBuilder, bucketAgg *BucketAgg, metrics []*Metr
|
||||
}
|
||||
|
||||
if orderBy, err := bucketAgg.Settings.Get("orderBy").String(); err == nil {
|
||||
a.Order[orderBy] = bucketAgg.Settings.Get("order").MustString("desc")
|
||||
/*
|
||||
The format for extended stats and percentiles is {metricId}[bucket_path]
|
||||
for everything else it's just {metricId}, _count, _term, or _key
|
||||
*/
|
||||
metricIdRegex := regexp.MustCompile(`^(\d+)`)
|
||||
metricId := metricIdRegex.FindString(orderBy)
|
||||
|
||||
if _, err := strconv.Atoi(orderBy); err == nil {
|
||||
if len(metricId) > 0 {
|
||||
for _, m := range metrics {
|
||||
if m.ID == orderBy {
|
||||
b.Metric(m.ID, m.Type, m.Field, nil)
|
||||
if m.ID == metricId {
|
||||
if m.Type == "count" {
|
||||
a.Order["_count"] = bucketAgg.Settings.Get("order").MustString("desc")
|
||||
} else {
|
||||
a.Order[orderBy] = bucketAgg.Settings.Get("order").MustString("desc")
|
||||
b.Metric(m.ID, m.Type, m.Field, nil)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
} else {
|
||||
a.Order[orderBy] = bucketAgg.Settings.Get("order").MustString("desc")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -127,6 +127,80 @@ func TestExecuteTimeSeriesQuery(t *testing.T) {
|
||||
So(avgAgg.Aggregation.Type, ShouldEqual, "avg")
|
||||
})
|
||||
|
||||
Convey("With term agg and order by count metric agg", func() {
|
||||
c := newFakeClient(5)
|
||||
_, err := executeTsdbQuery(c, `{
|
||||
"timeField": "@timestamp",
|
||||
"bucketAggs": [
|
||||
{
|
||||
"type": "terms",
|
||||
"field": "@host",
|
||||
"id": "2",
|
||||
"settings": { "size": "5", "order": "asc", "orderBy": "1" }
|
||||
},
|
||||
{ "type": "date_histogram", "field": "@timestamp", "id": "3" }
|
||||
],
|
||||
"metrics": [
|
||||
{"type": "count", "id": "1" }
|
||||
]
|
||||
}`, from, to, 15*time.Second)
|
||||
So(err, ShouldBeNil)
|
||||
sr := c.multisearchRequests[0].Requests[0]
|
||||
|
||||
termsAgg := sr.Aggs[0].Aggregation.Aggregation.(*es.TermsAggregation)
|
||||
So(termsAgg.Order["_count"], ShouldEqual, "asc")
|
||||
})
|
||||
|
||||
Convey("With term agg and order by percentiles agg", func() {
|
||||
c := newFakeClient(5)
|
||||
_, err := executeTsdbQuery(c, `{
|
||||
"timeField": "@timestamp",
|
||||
"bucketAggs": [
|
||||
{
|
||||
"type": "terms",
|
||||
"field": "@host",
|
||||
"id": "2",
|
||||
"settings": { "size": "5", "order": "asc", "orderBy": "1[95.0]" }
|
||||
},
|
||||
{ "type": "date_histogram", "field": "@timestamp", "id": "3" }
|
||||
],
|
||||
"metrics": [
|
||||
{"type": "percentiles", "field": "@value", "id": "1", "settings": { "percents": ["95","99"] } }
|
||||
]
|
||||
}`, from, to, 15*time.Second)
|
||||
So(err, ShouldBeNil)
|
||||
sr := c.multisearchRequests[0].Requests[0]
|
||||
|
||||
orderByAgg := sr.Aggs[0].Aggregation.Aggs[0]
|
||||
So(orderByAgg.Key, ShouldEqual, "1")
|
||||
So(orderByAgg.Aggregation.Type, ShouldEqual, "percentiles")
|
||||
})
|
||||
|
||||
Convey("With term agg and order by extended stats agg", func() {
|
||||
c := newFakeClient(5)
|
||||
_, err := executeTsdbQuery(c, `{
|
||||
"timeField": "@timestamp",
|
||||
"bucketAggs": [
|
||||
{
|
||||
"type": "terms",
|
||||
"field": "@host",
|
||||
"id": "2",
|
||||
"settings": { "size": "5", "order": "asc", "orderBy": "1[std_deviation]" }
|
||||
},
|
||||
{ "type": "date_histogram", "field": "@timestamp", "id": "3" }
|
||||
],
|
||||
"metrics": [
|
||||
{"type": "extended_stats", "field": "@value", "id": "1", "meta": { "std_deviation": true } }
|
||||
]
|
||||
}`, from, to, 15*time.Second)
|
||||
So(err, ShouldBeNil)
|
||||
sr := c.multisearchRequests[0].Requests[0]
|
||||
|
||||
orderByAgg := sr.Aggs[0].Aggregation.Aggs[0]
|
||||
So(orderByAgg.Key, ShouldEqual, "1")
|
||||
So(orderByAgg.Aggregation.Type, ShouldEqual, "extended_stats")
|
||||
})
|
||||
|
||||
Convey("With term agg and order by term", func() {
|
||||
c := newFakeClient(5)
|
||||
_, err := executeTsdbQuery(c, `{
|
||||
|
||||
Reference in New Issue
Block a user