Преглед изворни кода

feat(elasticsearch): terms aggregation options are working, things are starting to come together, #1034

Torkel Ödegaard пре 10 година
родитељ
комит
3e9aca3ed4

+ 0 - 23
public/app/plugins/datasource/elasticsearch/advancedOptions.js

@@ -1,23 +0,0 @@
-define([
-  'angular',
-  'lodash',
-  'jquery',
-],
-function (angular, _, $) {
-  'use strict';
-
-  angular
-    .module('grafana.directives')
-    .directive('tightFormAdvancedOption', function($compile, uiSegmentSrv, $q) {
-      return {
-        templateUrl: 'app/plugins/datasource/elasticsearch/partials/advancedOption.html',
-        restrict: 'E',
-        scope: {
-          model: "=",
-          option: "=",
-        },
-        link: function postLink($scope, elem) {
-        }
-      };
-    });
-});

+ 73 - 90
public/app/plugins/datasource/elasticsearch/bucketAgg.js

@@ -1,112 +1,95 @@
 define([
   'angular',
   'lodash',
-  'jquery',
+  './queryDef',
 ],
-function (angular, _, $) {
+function (angular, _, queryDef) {
   'use strict';
 
   var module = angular.module('grafana.directives');
 
-    module.controller('ElasticBucketAggCtrl', function($scope, uiSegmentSrv, $q) {
-      var bucketAggs = $scope.target.bucketAggs;
-
-      $scope.bucketAggTypes = [
-        {text: "Terms",           value: 'terms' },
-        {text: "Date Histogram",  value: 'date_histogram' },
-      ];
-
-      $scope.orderOptions = [
-        {text: "Top",     value: 'desc' },
-        {text: "Bottom",  value: 'asc' },
-      ];
-
-      $scope.sizeOptions = [
-        {text: "No limit", value: '0' },
-        {text: "1", value: '1' },
-        {text: "2", value: '2' },
-        {text: "3", value: '4' },
-        {text: "5", value: '5' },
-        {text: "10", value: '10' },
-        {text: "15", value: '15' },
-        {text: "20", value: '20' },
-      ];
-
-      $scope.$watch("index", function() {
-        $scope.isFirst = $scope.index === 0;
-        $scope.isLast = $scope.index === bucketAggs.length - 1;
-      });
-
-      $scope.init = function() {
-        $scope.agg = bucketAggs[$scope.index];
-        $scope.modelIsValid();
-      };
-
-      $scope.onChangeInternal = function() {
-        if ($scope.modelIsValid()) {
-          $scope.onChange();
-        }
-      };
+  module.controller('ElasticBucketAggCtrl', function($scope, uiSegmentSrv, $q, $rootScope) {
+    var bucketAggs = $scope.target.bucketAggs;
 
-      $scope.modelIsValid = function() {
-        if ($scope.agg.type === "terms") {
-          $scope.aggOptionsString = "Top 5, Order by: sum @value";
+    $scope.orderByOptions = [];
+    $scope.bucketAggTypes = queryDef.bucketAggTypes;
+    $scope.orderOptions = queryDef.orderOptions;
+    $scope.sizeOptions = queryDef.sizeOptions;
 
-          $scope.agg.order = $scope.agg.order || "desc";
-          $scope.agg.size = $scope.agg.size || "0";
-          $scope.agg.orderBy = $scope.agg.orderBy || "_count";
-        }
-        return true;
-      };
+    $rootScope.onAppEvent('elastic-query-updated', function() {
+      $scope.validateModel();
+      $scope.updateOrderByOptions();
+    });
 
-      $scope.toggleOptions = function() {
-        $scope.showOptions = !$scope.showOptions;
+    $scope.init = function() {
+      $scope.agg = bucketAggs[$scope.index];
+      $scope.validateModel();
+    };
 
-        $scope.orderByOptions = [
-          {text: "Doc Count", value: '_count' },
-          {text: "Term name", value: '_term' },
-          {text: "Average of @value", value: '1' },
-        ];
+    $scope.onChangeInternal = function() {
+      if ($scope.validateModel()) {
+        $scope.onChange();
       }
+    };
+
+    $scope.validateModel = function() {
+      $scope.isFirst = $scope.index === 0;
+      $scope.isLast = $scope.index === bucketAggs.length - 1;
+      $scope.aggOptionsString = "";
+
+      if ($scope.agg.type === "terms") {
+        $scope.agg.order = $scope.agg.order || "desc";
+        $scope.agg.size = $scope.agg.size || "0";
+        $scope.agg.orderBy = $scope.agg.orderBy || "_count";
+
+        if ($scope.agg.size === '0') {
+          $scope.aggOptionsString = "";
+        } else {
+          $scope.aggOptionsString = queryDef.describeOrder($scope.agg.order) + ' ' + $scope.agg.size + ', '
+        }
+        $scope.aggOptionsString += 'Order by: ' + queryDef.describeOrderBy($scope.agg.orderBy, $scope.target);
 
-      $scope.addBucketAgg = function() {
-        // if last is date histogram add it before
-        var lastBucket = bucketAggs[bucketAggs.length - 1];
-        var addIndex = bucketAggs.length - 1;
-
-        if (lastBucket && lastBucket.type === 'date_histogram') {
-          addIndex - 1;
+        if ($scope.agg.size === '0') {
+          $scope.aggOptionsString += ' (' + $scope.agg.order + ')';
         }
+      }
 
-        var id = _.reduce($scope.target.bucketAggs.concat($scope.target.metrics), function(max, val) {
-          return parseInt(val.id) > max ? parseInt(val.id) : max;
-        }, 0);
+      return true;
+    };
 
-        bucketAggs.splice(addIndex, 0, {type: "terms", field: "select field", id: (id+1).toString()});
-      };
+    $scope.toggleOptions = function() {
+      $scope.showOptions = !$scope.showOptions;
+      $scope.updateOrderByOptions();
+    };
 
-      $scope.removeBucketAgg = function() {
-        bucketAggs.splice($scope.index, 1);
-        $scope.onChange();
-      };
+    $scope.updateOrderByOptions = function() {
+      $scope.orderByOptions = queryDef.getOrderByOptions($scope.target);
+    };
 
-      $scope.init();
+    $scope.addBucketAgg = function() {
+      // if last is date histogram add it before
+      var lastBucket = bucketAggs[bucketAggs.length - 1];
+      var addIndex = bucketAggs.length - 1;
 
-    });
+      if (lastBucket && lastBucket.type === 'date_histogram') {
+        addIndex - 1;
+      }
+
+      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.onChange();
+    };
+
+    $scope.removeBucketAgg = function() {
+      bucketAggs.splice($scope.index, 1);
+      $scope.onChange();
+    };
+
+    $scope.init();
+
+  });
 
-    module.directive('elasticBucketAgg', function() {
-      return {
-        templateUrl: 'app/plugins/datasource/elasticsearch/partials/bucketAgg.html',
-        controller: 'ElasticBucketAggCtrl',
-        restrict: 'E',
-        scope: {
-          target: "=",
-          index: "=",
-          onChange: "&",
-          getFields: "&",
-        },
-        link: function postLink($scope, elem) {
-        }
-      };
-    });
 });

+ 28 - 0
public/app/plugins/datasource/elasticsearch/directives.js

@@ -20,4 +20,32 @@ function (angular) {
     return {templateUrl: 'app/plugins/datasource/elasticsearch/partials/annotations.editor.html'};
   });
 
+  module.directive('elasticMetricAgg', function() {
+    return {
+      templateUrl: 'app/plugins/datasource/elasticsearch/partials/metricAgg.html',
+      controller: 'ElasticMetricAggCtrl',
+      restrict: 'E',
+      scope: {
+        target: "=",
+        index: "=",
+        onChange: "&",
+        getFields: "&",
+      }
+    };
+  });
+
+  module.directive('elasticBucketAgg', function() {
+    return {
+      templateUrl: 'app/plugins/datasource/elasticsearch/partials/bucketAgg.html',
+      controller: 'ElasticBucketAggCtrl',
+      restrict: 'E',
+      scope: {
+        target: "=",
+        index: "=",
+        onChange: "&",
+        getFields: "&",
+      }
+    };
+  });
+
 });

+ 31 - 53
public/app/plugins/datasource/elasticsearch/metricAgg.js

@@ -1,74 +1,52 @@
 define([
   'angular',
   'lodash',
-  'jquery',
+  './queryDef'
 ],
-function (angular, _, $) {
+function (angular, _, queryDef) {
   'use strict';
 
   var module = angular.module('grafana.directives');
 
-    module.controller('ElasticMetricAggCtrl', function($scope, uiSegmentSrv, $q) {
-      var metricAggs = $scope.target.metrics;
+  module.controller('ElasticMetricAggCtrl', function($scope, uiSegmentSrv, $q) {
+    var metricAggs = $scope.target.metrics;
 
-      $scope.metricAggTypes = [
-        {text: "Count",           value: 'count' },
-        {text: "Average of",  value: 'avg' },
-        {text: "Sum of",  value: 'sum' },
-        {text: "Max of",  value: 'max' },
-        {text: "Min of",  value: 'min' },
-        {text: "Standard Deviations",  value: 'std_dev' },
-      ];
+    $scope.metricAggTypes = queryDef.metricAggTypes;
 
-      $scope.init = function() {
-        $scope.agg = metricAggs[$scope.index];
-        if (!$scope.agg.field) {
-          $scope.agg.field = 'select field';
-        }
+    $scope.init = function() {
+      $scope.agg = metricAggs[$scope.index];
+      if (!$scope.agg.field) {
+        $scope.agg.field = 'select field';
       }
+    }
 
-      $scope.$watchCollection("target.metrics", function() {
-        $scope.isFirst = $scope.index === 0;
-        $scope.isLast = $scope.index === metricAggs.length - 1;
-        $scope.isSingle = metricAggs.length === 1;
-      });
+    $scope.$watchCollection("target.metrics", function() {
+      $scope.isFirst = $scope.index === 0;
+      $scope.isLast = $scope.index === metricAggs.length - 1;
+      $scope.isSingle = metricAggs.length === 1;
+    });
 
-      $scope.toggleOptions = function() {
-        $scope.showOptions = !$scope.showOptions;
-      }
+    $scope.toggleOptions = function() {
+      $scope.showOptions = !$scope.showOptions;
+    }
 
-      $scope.addMetricAgg = function() {
-        var addIndex = metricAggs.length;
+    $scope.addMetricAgg = function() {
+      var addIndex = metricAggs.length;
 
-        var id = _.reduce($scope.target.bucketAggs.concat($scope.target.metrics), function(max, val) {
-          return parseInt(val.id) > max ? parseInt(val.id) : max;
-        }, 0);
+      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()});
-      };
+      metricAggs.splice(addIndex, 0, {type: "count", field: "select field", id: (id+1).toString()});
+    };
 
-      $scope.removeMetricAgg = function() {
-        metricAggs.splice($scope.index, 1);
-        $scope.onChange();
-      };
+    $scope.removeMetricAgg = function() {
+      metricAggs.splice($scope.index, 1);
+      $scope.onChange();
+    };
 
-      $scope.init();
+    $scope.init();
 
-    });
+  });
 
-    module.directive('elasticMetricAgg', function() {
-      return {
-        templateUrl: 'app/plugins/datasource/elasticsearch/partials/metricAgg.html',
-        controller: 'ElasticMetricAggCtrl',
-        restrict: 'E',
-        scope: {
-          target: "=",
-          index: "=",
-          onChange: "&",
-          getFields: "&",
-        },
-        link: function postLink($scope, elem) {
-        }
-      };
-    });
 });

+ 1 - 1
public/app/plugins/datasource/elasticsearch/partials/bucketAgg.html

@@ -51,7 +51,7 @@
 		<div class="tight-form last">
 			<ul class="tight-form-list">
 				<li class="tight-form-item" style="width: 60px">
-					By
+					Order By
 				</li>
 				<li>
 					<metric-segment-model property="agg.orderBy" options="orderByOptions" on-change="onChangeInternal()" css-class="last"></metric-segment-model>

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

@@ -16,24 +16,7 @@ function (angular, _, ElasticQueryBuilder) {
 
       target.timeField = target.timeField || '@timestamp';
       target.metrics = target.metrics || [{ type: 'count', id: '1' }];
-      target.bucketAggs = target.bucketAggs || [];
-      target.bucketAggs = [
-        {
-          type: 'terms',
-          field: '@hostname',
-          id: '2'
-        },
-        {
-          type: 'date_histogram',
-          field: '@timestamp',
-          id: '3'
-        },
-      ];
-
-      $scope.timeSegment = uiSegmentSrv.newSegment(target.timeField);
-
-      $scope.removeSelectSegment = uiSegmentSrv.newSegment({fake: true, value: '-- remove select --'});
-      $scope.resetSelectSegment = uiSegmentSrv.newSegment({fake: true, value: '-- reset --'});
+      target.bucketAggs = target.bucketAggs || [{ type: 'date_histogram', field: '@timestmap', id: '2'}];
 
       $scope.queryBuilder = new ElasticQueryBuilder(target);
       $scope.rawQueryOld = angular.toJson($scope.queryBuilder.build($scope.target), true);
@@ -46,12 +29,13 @@ function (angular, _, ElasticQueryBuilder) {
     };
 
     $scope.queryUpdated = function() {
-      console.log('qery updated');
       var newJson = angular.toJson($scope.queryBuilder.build($scope.target), true);
       if (newJson !== $scope.oldQueryRaw) {
         $scope.rawQueryOld = newJson;
         $scope.get_data();
       }
+
+      $scope.appEvent('elastic-query-updated');
     };
 
     $scope.transformToSegments = function(addTemplateVars) {
@@ -65,7 +49,6 @@ function (angular, _, ElasticQueryBuilder) {
             segments.unshift(uiSegmentSrv.newSegment({ type: 'template', value: '$' + variable.name, expandable: true }));
           });
         }
-
         return segments;
       };
     };

+ 79 - 0
public/app/plugins/datasource/elasticsearch/queryDef.js

@@ -0,0 +1,79 @@
+define([
+  'lodash'
+],
+function (_) {
+  'use strict';
+
+  return {
+    metricAggTypes: [
+      {text: "Count",   value: 'count' },
+      {text: "Average of",  value: 'avg' },
+      {text: "Sum of",  value: 'sum' },
+      {text: "Max of",  value: 'max' },
+      {text: "Min of",  value: 'min' },
+      {text: "Standard Deviations",  value: 'std_dev' },
+    ],
+
+    bucketAggTypes: [
+      {text: "Terms",           value: 'terms' },
+      {text: "Date Histogram",  value: 'date_histogram' },
+    ],
+
+    orderByOptions: [
+      {text: "Doc Count",  value: '_count' },
+      {text: "Term value", value: '_term' },
+    ],
+
+    orderOptions: [
+      {text: "Top",     value: 'desc' },
+      {text: "Bottom",  value: 'asc' },
+    ],
+
+    sizeOptions: [
+      {text: "No limit", value: '0' },
+      {text: "1", value: '1' },
+      {text: "2", value: '2' },
+      {text: "3", value: '4' },
+      {text: "5", value: '5' },
+      {text: "10", value: '10' },
+      {text: "15", value: '15' },
+      {text: "20", value: '20' },
+    ],
+
+    getOrderByOptions: function(target) {
+      var self = this;
+      var metricRefs = [];
+      _.each(target.metrics, function(metric) {
+        if (metric.type !== 'count') {
+          metricRefs.push({text: self.describeMetric(metric), value: metric.id});
+        }
+      });
+
+      return this.orderByOptions.concat(metricRefs);
+    },
+
+    describeOrder: function(order) {
+      var def = _.findWhere(this.orderOptions, {value: order});
+      return def.text;
+    },
+
+    describeMetric: function(metric) {
+      var def = _.findWhere(this.metricAggTypes, {value: metric.type});
+      return def.text + ' ' + metric.field;
+    },
+
+    describeOrderBy: function(orderBy, target) {
+      var def = _.findWhere(this.orderByOptions, {value: orderBy});
+      if (def) {
+        return def.text;
+      }
+      var metric = _.findWhere(target.metrics, {id: orderBy});
+      if (metric) {
+        return this.describeMetric(metric);
+      } else {
+        return "metric not found";
+      }
+    },
+  };
+
+});