فهرست منبع

feat(adhoc filters): basic implementation for ad hoc filters for elasticsearch, #6038

Torkel Ödegaard 9 سال پیش
والد
کامیت
a01836e86d

+ 1 - 1
public/app/features/templating/editor_ctrl.ts

@@ -84,7 +84,7 @@ export class VariableEditorCtrl {
       if ($scope.current.type === 'adhoc' && $scope.current.datasource !== null) {
         $scope.infoText = 'Adhoc filters are applied automatically to all queries that target this datasource';
         datasourceSrv.get($scope.current.datasource).then(ds => {
-          if (!ds.supportAdhocFilters) {
+          if (!ds.getTagKeys) {
             $scope.infoText = 'This datasource does not support adhoc filters yet.';
           }
         });

+ 13 - 2
public/app/plugins/datasource/elasticsearch/datasource.js

@@ -177,11 +177,14 @@ function (angular, _, moment, kbn, ElasticQueryBuilder, IndexPattern, ElasticRes
       var target;
       var sentTargets = [];
 
+      // add global adhoc filters to timeFilter
+      var adhocFilters = templateSrv.getAdhocFilters(this.name);
+
       for (var i = 0; i < options.targets.length; i++) {
         target = options.targets[i];
         if (target.hide) {continue;}
 
-        var queryObj = this.queryBuilder.build(target);
+        var queryObj = this.queryBuilder.build(target, adhocFilters);
         var esQuery = angular.toJson(queryObj);
         var luceneQuery = target.query || '*';
         luceneQuery = templateSrv.replace(luceneQuery, options.scopedVars, 'lucene');
@@ -247,7 +250,7 @@ function (angular, _, moment, kbn, ElasticQueryBuilder, IndexPattern, ElasticRes
               // Hide meta-fields and check field type
               if (key[0] !== '_' &&
                   (!query.type ||
-                    query.type && typeMap[subObj.type] === query.type)) {
+                   query.type && typeMap[subObj.type] === query.type)) {
 
                 fields[fieldName] = {
                   text: fieldName,
@@ -314,6 +317,14 @@ function (angular, _, moment, kbn, ElasticQueryBuilder, IndexPattern, ElasticRes
         return this.getTerms(query);
       }
     };
+
+    this.getTagKeys = function() {
+      return this.getFields({});
+    };
+
+    this.getTagValues = function(options) {
+      return this.getTerms({field: options.key, query: '*'});
+    };
   }
 
   return {

+ 19 - 1
public/app/plugins/datasource/elasticsearch/query_builder.js

@@ -98,7 +98,23 @@ function (queryDef) {
     return query;
   };
 
-  ElasticQueryBuilder.prototype.build = function(target) {
+  ElasticQueryBuilder.prototype.addAdhocFilters = function(query, adhocFilters) {
+    if (!adhocFilters) {
+      return;
+    }
+
+    var i, filter, condition;
+    var must = query.query.filtered.filter.bool.must;
+
+    for (i = 0; i < adhocFilters.length; i++) {
+      filter = adhocFilters[i];
+      condition = {};
+      condition[filter.key] = filter.value;
+      must.push({"term": condition});
+    }
+  };
+
+  ElasticQueryBuilder.prototype.build = function(target, adhocFilters) {
     // make sure query has defaults;
     target.metrics = target.metrics || [{ type: 'count', id: '1' }];
     target.dsType = 'elasticsearch';
@@ -125,6 +141,8 @@ function (queryDef) {
       }
     };
 
+    this.addAdhocFilters(query, adhocFilters);
+
     // handle document query
     if (target.bucketAggs.length === 0) {
       metric = target.metrics[0];

+ 12 - 0
public/app/plugins/datasource/elasticsearch/specs/query_builder_specs.ts

@@ -238,4 +238,16 @@ describe('ElasticQueryBuilder', function() {
     expect(firstLevel.aggs["2"].derivative.buckets_path).to.be("3");
   });
 
+  it('with adhoc filters', function() {
+    var query = builder.build({
+      metrics: [{type: 'Count', id: '0'}],
+      timeField: '@timestamp',
+      bucketAggs: [{type: 'date_histogram', field: '@timestamp', id: '3'}],
+    }, [
+      {key: 'key1', operator: '=', value: 'value1'}
+    ]);
+
+    expect(query.query.filtered.filter.bool.must[1].term["key1"]).to.be("value1");
+  });
+
 });

+ 1 - 2
public/app/plugins/datasource/influxdb/datasource.ts

@@ -9,6 +9,7 @@ import InfluxQuery from './influx_query';
 import ResponseParser from './response_parser';
 import InfluxQueryBuilder from './query_builder';
 
+
 export default class InfluxDatasource {
   type: string;
   urls: any;
@@ -21,7 +22,6 @@ export default class InfluxDatasource {
   interval: any;
   supportAnnotations: boolean;
   supportMetrics: boolean;
-  supportAdhocFilters: boolean;
   responseParser: any;
 
   /** @ngInject */
@@ -40,7 +40,6 @@ export default class InfluxDatasource {
     this.interval = (instanceSettings.jsonData || {}).timeInterval;
     this.supportAnnotations = true;
     this.supportMetrics = true;
-    this.supportAdhocFilters = true;
     this.responseParser = new ResponseParser();
   }
 

+ 1 - 0
public/test/specs/helpers.js

@@ -158,6 +158,7 @@ define([
       return _.template(text, this.templateSettings)(this.data);
     };
     this.init = function() {};
+    this.getAdhocFilters = function() { return []; };
     this.fillVariableValuesForUrl = function() {};
     this.updateTemplateData = function() { };
     this.variableExists = function() { return false; };