Explorar el Código

feat(elasticsearch): added bucket agg id concept

Torkel Ödegaard hace 10 años
padre
commit
f1e995ec79

+ 6 - 2
public/app/plugins/datasource/elasticsearch/bucketAgg.js

@@ -65,7 +65,7 @@ function (angular, _, $) {
         $scope.orderByOptions = [
           {text: "Doc Count", value: '_count' },
           {text: "Term name", value: '_term' },
-          {text: "Average of @value", value: '0' },
+          {text: "Average of @value", value: 'm0' },
         ];
       }
 
@@ -78,7 +78,11 @@ function (angular, _, $) {
           addIndex - 1;
         }
 
-        bucketAggs.splice(addIndex, 0, {type: "terms", field: "select field" });
+        var id = _.reduce($scope.target.bucketAggs.concat($scope.target.metrics), function(max, val) {
+          return parseInt(val.id) > max ? parseInt(val.id) : max;
+        }, 0);
+
+        bucketAggs.splice(addIndex, 0, {type: "terms", field: "select field", id: (id+1).toString()});
       };
 
       $scope.removeBucketAgg = function() {

+ 16 - 12
public/app/plugins/datasource/elasticsearch/datasource.js

@@ -174,18 +174,19 @@ function (angular, _, config, kbn, moment, ElasticQueryBuilder) {
 
     // This is quite complex
     // neeed to recurise down the nested buckets to build series
-    ElasticDatasource.prototype._processBuckets = function(buckets, target, series, level, parentName) {
-      var seriesName, value, metric, i, y, bucket, childBucket;
+    ElasticDatasource.prototype._processBuckets = function(aggs, target, series, level, parentName) {
+      var seriesName, value, metric, i, y, bucket, childBucket, aggDef, esAgg;
+      var buckets;
+      var dataFound = 0;
 
-      for (i = 0; i < buckets.length; i++) {
-        bucket = buckets[i];
-        childBucket = bucket['b' + level];
+      aggDef = target.bucketAggs[level];
+      esAgg = aggs[aggDef.id];
 
-        if (childBucket && childBucket.buckets) {
-          seriesName = parentName + ' ' + bucket.key;
-          this._processBuckets(childBucket.buckets, target, series, level+1, seriesName);
-        } else {
+      for (i = 0; i < esAgg.buckets.length; i++) {
+        bucket = esAgg.buckets[i];
 
+        // if last agg collect series
+        if (level === target.bucketAggs.length - 1) {
           for (y = 0; y < target.metrics.length; y++) {
             metric = target.metrics[y];
             seriesName = parentName;
@@ -195,13 +196,16 @@ function (angular, _, config, kbn, moment, ElasticQueryBuilder) {
               value = bucket.doc_count;
             } else {
               seriesName += ' ' + metric.field + ' ' + metric.type;
-              value = bucket['m' + y.toString()].value;
+              value = bucket[metric.id].value;
             }
 
             var serie = series[seriesName] = series[seriesName] || {target: seriesName, datapoints: []};
             serie.datapoints.push([value, bucket.key]);
           }
         }
+        else {
+          this._processBuckets(bucket, target, series, level+1, parentName + ' ' + bucket.key);
+        }
       }
     };
 
@@ -214,11 +218,11 @@ function (angular, _, config, kbn, moment, ElasticQueryBuilder) {
           throw { message: response.error };
         }
 
-        var buckets = response.aggregations["b0"].buckets;
+        var aggregations = response.aggregations;
         var target = targets[i];
         var querySeries = {};
 
-        this._processBuckets(buckets, target, querySeries, 1, target.refId);
+        this._processBuckets(aggregations, target, querySeries, 0, target.refId);
 
         for (var prop in querySeries) {
           if (querySeries.hasOwnProperty(prop)) {

+ 6 - 1
public/app/plugins/datasource/elasticsearch/metricAgg.js

@@ -39,7 +39,12 @@ function (angular, _, $) {
 
       $scope.addMetricAgg = function() {
         var addIndex = metricAggs.length;
-        metricAggs.splice(addIndex, 0, {type: "count", field: "select field" });
+
+        var id = _.reduce($scope.target.bucketAggs.concat($scope.target.metrics), function(max, val) {
+          return parseInt(val.id) > max ? parseInt(val.id) : max;
+        }, 0);
+
+        metricAggs.splice(addIndex, 0, {type: "count", field: "select field", id: (id+1).toString()});
       };
 
       $scope.removeMetricAgg = function() {

+ 9 - 3
public/app/plugins/datasource/elasticsearch/queryBuilder.js

@@ -54,13 +54,19 @@ function (angular) {
           break;
         }
         case 'terms': {
-          esAgg["terms"] = { "field": aggDef.field };
+          esAgg.terms = { "field": aggDef.field };
+          var size = parseInt(aggDef.size, 10);
+          if (size > 0) { esAgg.terms.size = size; }
+          if (aggDef.orderBy) {
+            esAgg.terms.order = {};
+            esAgg.terms.order[aggDef.orderBy] = aggDef.order;
+          }
           break;
         }
       }
 
       nestedAggs.aggs = {};
-      nestedAggs.aggs['b' + i] = esAgg;
+      nestedAggs.aggs[aggDef.id] = esAgg;
       nestedAggs = esAgg;
     }
 
@@ -74,7 +80,7 @@ function (angular) {
 
       var aggField = {};
       aggField[metric.type] = {field: metric.field};
-      nestedAggs.aggs['m' + i] = aggField;
+      nestedAggs.aggs[metric.id] = aggField;
     }
 
     return query;

+ 5 - 3
public/app/plugins/datasource/elasticsearch/queryCtrl.js

@@ -15,16 +15,18 @@ function (angular, _, ElasticQueryBuilder) {
       if (!target) { return; }
 
       target.timeField = target.timeField || '@timestamp';
-      target.metrics = target.metrics || [{ type: 'count' }];
+      target.metrics = target.metrics || [{ type: 'count', id: '1' }];
       target.bucketAggs = target.bucketAggs || [];
       target.bucketAggs = [
         {
           type: 'terms',
-          field: '@hostname'
+          field: '@hostname',
+          id: '2'
         },
         {
           type: 'date_histogram',
-          field: '@timestamp'
+          field: '@timestamp',
+          id: '3'
         },
       ];
 

+ 29 - 12
public/test/specs/elasticsearch-querybuilder-specs.js

@@ -9,29 +9,29 @@ define([
       var builder = new ElasticQueryBuilder();
 
       var query = builder.build({
-        metrics: [{type: 'Count'}],
+        metrics: [{type: 'Count', id: '0'}],
         timeField: '@timestamp',
-        bucketAggs: [{type: 'date_histogram', field: '@timestamp'}],
+        bucketAggs: [{type: 'date_histogram', field: '@timestamp', id: '1'}],
       });
 
       expect(query.query.filtered.filter.bool.must[0].range["@timestamp"].gte).to.be("$timeFrom");
-      expect(query.aggs["b0"].date_histogram.extended_bounds.min).to.be("$timeFrom");
+      expect(query.aggs["1"].date_histogram.extended_bounds.min).to.be("$timeFrom");
     });
 
     it('with multiple bucket aggs', function() {
       var builder = new ElasticQueryBuilder();
 
       var query = builder.build({
-        metrics: [{type: 'Count'}],
+        metrics: [{type: 'count', id: '1'}],
         timeField: '@timestamp',
         bucketAggs: [
-          {type: 'terms', field: '@host'},
-          {type: 'date_histogram', field: '@timestamp'}
+          {type: 'terms', field: '@host', id: '2'},
+          {type: 'date_histogram', field: '@timestamp', id: '3'}
         ],
       });
 
-      expect(query.aggs["b0"].terms.field).to.be("@host");
-      expect(query.aggs["b0"].aggs["b1"].date_histogram.field).to.be("@timestamp");
+      expect(query.aggs["2"].terms.field).to.be("@host");
+      expect(query.aggs["2"].aggs["3"].date_histogram.field).to.be("@timestamp");
     });
 
 
@@ -39,14 +39,31 @@ define([
       var builder = new ElasticQueryBuilder();
 
       var query = builder.build({
-        metrics: [{type: 'avg', field: '@value'}],
-        bucketAggs: [{type: 'date_histogram', field: '@timestamp'}],
+        metrics: [{type: 'avg', field: '@value', id: '1'}],
+        bucketAggs: [{type: 'date_histogram', field: '@timestamp', id: '2'}],
       }, 100, 1000);
 
-      var aggs = query.aggs["b0"].aggs;
-      expect(aggs["m0"].avg.field).to.be("@value");
+      var aggs = query.aggs["2"].aggs;
+      expect(aggs["1"].avg.field).to.be("@value");
     });
 
+    it('with term agg and order by metric agg', function() {
+      var builder = new ElasticQueryBuilder();
+
+      var query = builder.build({
+        metrics: [{type: 'avg', field: '@value', id: '1'}],
+        bucketAggs: [
+          {type: 'term', size: 5, order: 'asc', orderBy: 'm0', id: '2' },
+          {type: 'date_histogram', field: '@timestamp', id: '3'}
+        ],
+      }, 100, 1000);
+
+      var firstLevel = query.aggs["2"];
+      var secondLevel = firstLevel.aggs["3"];
+
+      // expect(firstLevel.aggs["m0"].avg.field).to.be("@value");
+      expect(secondLevel.aggs["1"].avg.field).to.be("@value");
+    });
 
   });
 

+ 0 - 21
public/test/specs/elasticsearch-queryctrl-specs.js

@@ -26,27 +26,6 @@ define([
         ctx.scope.init();
       });
 
-      it('should init selectSegments', function() {
-        expect(ctx.scope.selectSegments.length).to.be(2);
-      });
-
-      describe('initSelectSegments with 2 selects', function() {
-
-        it('init selectSegments', function() {
-          ctx.scope.target.metrics = [
-            {agg: 'count'},
-            {agg: 'avg', field: 'value'},
-          ];
-          ctx.scope.initSelectSegments();
-
-          expect(ctx.scope.selectSegments.length).to.be(5);
-          expect(ctx.scope.selectSegments[0].value).to.be('count');
-          expect(ctx.scope.selectSegments[1].value).to.be(' and ');
-          expect(ctx.scope.selectSegments[2].value).to.be('avg');
-          expect(ctx.scope.selectSegments[3].value).to.be('value');
-        });
-      });
-
     });
 
   });

+ 13 - 13
public/test/specs/elasticsearch-specs.js

@@ -23,12 +23,12 @@ define([
         beforeEach(function() {
           result = ctx.ds._processTimeSeries([{
             refId: 'A',
-            metrics: [{agg: 'count'}],
-            bucketAggs: [{type: 'date_histogram', field: '@timestamp'}],
+            metrics: [{type: 'count', id: '1'}],
+            bucketAggs: [{type: 'date_histogram', field: '@timestamp', id: '2'}],
           }], {
             responses: [{
               aggregations: {
-                "b0": {
+                "2": {
                   buckets: [
                     {
                       doc_count: 10,
@@ -60,20 +60,20 @@ define([
         beforeEach(function() {
           result = ctx.ds._processTimeSeries([{
             refId: 'A',
-            metrics: [{agg: 'count'}, {agg: 'avg', field: 'value'}],
-            bucketAggs: [{type: 'date_histogram', field: '@timestamp'}],
+            metrics: [{type: 'count', id: '1'}, {type: 'avg', field: 'value', id: '2'}],
+            bucketAggs: [{type: 'date_histogram', field: '@timestamp', id: '3'}],
           }], {
             responses: [{
               aggregations: {
-                "b0": {
+                "3": {
                   buckets: [
                     {
-                      "m1": {value: 88},
+                      "2": {value: 88},
                       doc_count: 10,
                       key: 1000
                     },
                     {
-                      "m1": {value: 99},
+                      "2": {value: 99},
                       doc_count: 15,
                       key: 2000
                     }
@@ -103,15 +103,15 @@ define([
         beforeEach(function() {
           result = ctx.ds._processTimeSeries([{
             refId: 'A',
-            metrics: [{agg: 'count'}],
-            bucketAggs: [{type: 'terms', field: 'host'}, {type: 'date_histogram', field: '@timestamp'}],
+            metrics: [{type: 'count', id: '1'}],
+            bucketAggs: [{type: 'terms', field: 'host', id: '2'}, {type: 'date_histogram', field: '@timestamp', id: '3'}],
           }], {
             responses: [{
               aggregations: {
-                "b0": {
+                "2": {
                   buckets: [
                     {
-                      "b1": {
+                      "3": {
                         buckets: [
                           {doc_count: 1, key: 1000},
                           {doc_count: 3, key: 2000}
@@ -121,7 +121,7 @@ define([
                       key: 'server1',
                     },
                     {
-                      "b1": {
+                      "3": {
                         buckets: [
                           {doc_count: 2, key: 1000},
                           {doc_count: 8, key: 2000}