Bläddra i källkod

feat(elasticsearch): finished work on adding support for filters aggregate, you can now split series by query using group by filters, closes #2785

Torkel Ödegaard 10 år sedan
förälder
incheckning
792b194d0e

+ 17 - 0
public/app/plugins/datasource/elasticsearch/bucketAgg.js

@@ -80,6 +80,15 @@ function (angular, _, queryDef) {
           break;
         }
         case 'filters': {
+          settings.filters = settings.filters || [{query: '*'}];
+          settingsLinkText = _.reduce(settings.filters, function(memo, value, index) {
+            memo += 'Q' + (index + 1) + '  = ' + value.query + ' ';
+            return memo;
+          }, '');
+          if (settingsLinkText.length > 50) {
+            settingsLinkText = settingsLinkText.substr(0, 50) + "...";
+          }
+          settingsLinkText = 'Filter Queries (' + settings.filters.length + ')';
           break;
         }
         case 'date_histogram': {
@@ -94,6 +103,14 @@ function (angular, _, queryDef) {
       return true;
     };
 
+    $scope.addFiltersQuery = function() {
+      $scope.agg.settings.filters.push({query: '*'});
+    };
+
+    $scope.removeFiltersQuery = function(filter) {
+      $scope.agg.settings.filters = _.without($scope.agg.settings.filters, filter);
+    };
+
     $scope.toggleOptions = function() {
       $scope.showOptions = !$scope.showOptions;
       $scope.updateOrderByOptions();

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

@@ -7,11 +7,11 @@
 		<li>
 			<metric-segment-model property="agg.type" options="bucketAggTypes" on-change="onTypeChanged()" custom="false" css-class="tight-form-item-large"></metric-segment-model>
 		</li>
-		<li ng-if="agg.type !== 'filters'">
+		<li ng-if="agg.field">
 			<metric-segment-model property="agg.field" get-options="getFields()" on-change="onChange()" css-class="tight-form-item-xxlarge"></metric-segment>
 		</li>
-		<li ng-if="agg.type === 'filters'">
-			<input type="text" class="tight-form-input tight-form-item-xxlarge" ng-model="agg.query" spellcheck='false' placeholder="Lucence query" ng-blur="onChange()">
+		<li ng-if="!agg.field">
+			<span class="tight-form-item tight-form-item-xxlarge">&nbsp;</span>
 		</li>
 		<li class="tight-form-item last" ng-if="settingsLinkText">
 			<a ng-click="toggleOptions()">{{settingsLinkText}}</a>
@@ -78,6 +78,27 @@
 			<div class="clearfix"></div>
 		</div>
 	</div>
+	<div class="tight-form-inner-box" ng-if="agg.type === 'filters'">
+		<div class="tight-form" ng-repeat="filter in agg.settings.filters" ng-class="{last: $last}">
+			<ul class="tight-form-list">
+				<li class="tight-form-item" style="width: 100px">
+					Query {{$index + 1}}
+				</li>
+				<li>
+					<input type="text" class="tight-form-input input-large" ng-model="filter.query" spellcheck='false' placeholder="Lucence query" ng-blur="onChangeInternal()">
+				</li>
+				<li class="tight-form-item last" ng-if="$first">
+					<a class="pointer" ng-click="addFiltersQuery()"><i class="fa fa-plus"></i></a>
+				</li>
+				<li class="tight-form-item last" ng-if="!$first">
+					<a class="pointer" ng-click="removeFiltersQuery(filter)"><i class="fa fa-minus"></i></a>
+				</li>
+			</ul>
+			<div class="clearfix"></div>
+		</div>
+
+	</div>
+
 </div>
 
 

+ 7 - 16
public/app/plugins/datasource/elasticsearch/queryBuilder.js

@@ -54,19 +54,15 @@ function (angular) {
     }
   };
 
-  ElasticQueryBuilder.prototype.getFiltersAgg = function(target) {
+  ElasticQueryBuilder.prototype.getFiltersAgg = function(aggDef) {
     var filterObj = {};
 
-    for (var i = 0; i < target.bucketAggs.length; i++) {
-      var aggDef = target.bucketAggs[i];
-      if (aggDef.type !== 'filters') {
-        continue;
-      }
-
-      filterObj[aggDef.query] = {
+    for (var i = 0; i < aggDef.settings.filters.length; i++) {
+      var query = aggDef.settings.filters[i].query;
+      filterObj[query] = {
         query: {
           query_string: {
-            query: aggDef.query,
+            query: query,
             analyze_wildcard: true
           }
         }
@@ -81,7 +77,7 @@ function (angular) {
       return angular.fromJson(target.rawQuery);
     }
 
-    var i, nestedAggs, metric, filtersHandled;
+    var i, nestedAggs, metric;
     var query = {
       "size": 0,
       "query": {
@@ -118,12 +114,7 @@ function (angular) {
           break;
         }
         case 'filters': {
-          // skip filters if we already processed them
-          if (filtersHandled) {
-            continue;
-          }
-          esAgg["filters"] = {filters: this.getFiltersAgg(target)};
-          filtersHandled = true;
+          esAgg["filters"] = {filters: this.getFiltersAgg(aggDef)};
           break;
         }
         case 'terms': {

+ 10 - 2
public/test/specs/elasticsearch-querybuilder-specs.js

@@ -100,8 +100,16 @@ define([
         metrics: [{type: 'count', id: '1'}],
         timeField: '@timestamp',
         bucketAggs: [
-          {type: 'filters', query:  '@metric:cpu', id: '2'},
-          {type: 'filters', query:  '@metric:logins.count', id: '3' },
+          {
+            id: '2',
+            type: 'filters',
+            settings: {
+              filters: [
+                {query: '@metric:cpu' },
+                {query: '@metric:logins.count' },
+              ]
+            }
+          },
           {type: 'date_histogram', field: '@timestamp', id: '4'}
         ],
       });

+ 10 - 2
public/test/specs/elasticsearch-response-specs.js

@@ -359,8 +359,16 @@ define([
           refId: 'A',
           metrics: [{type: 'count', id: '1'}],
           bucketAggs: [
-            {type: 'filters', query: '@metric:cpu', id: '2'},
-            {type: 'filters', query: '@metric:logins.count', id: '5'},
+            {
+              id: '2',
+              type: 'filters',
+              settings: {
+                filters: [
+                  {query: '@metric:cpu' },
+                  {query: '@metric:logins.count' },
+                ]
+              }
+            },
             {type: 'date_histogram', field: '@timestamp', id: '3'}
           ],
         }];