-
diff --git a/public/app/plugins/datasource/elasticsearch/queryBuilder.js b/public/app/plugins/datasource/elasticsearch/queryBuilder.js
index 09e72dee9eb..d9b58d5acdf 100644
--- a/public/app/plugins/datasource/elasticsearch/queryBuilder.js
+++ b/public/app/plugins/datasource/elasticsearch/queryBuilder.js
@@ -105,7 +105,7 @@ function (angular) {
var metricAgg = {field: metric.field};
for (var prop in metric.settings) {
- if (metric.settings.hasOwnProperty(prop)) {
+ if (metric.settings.hasOwnProperty(prop) && metric.settings[prop] !== null) {
metricAgg[prop] = metric.settings[prop];
}
}
diff --git a/public/app/plugins/datasource/elasticsearch/queryDef.js b/public/app/plugins/datasource/elasticsearch/queryDef.js
index 428f026e0dc..5fe11e36327 100644
--- a/public/app/plugins/datasource/elasticsearch/queryDef.js
+++ b/public/app/plugins/datasource/elasticsearch/queryDef.js
@@ -13,6 +13,7 @@ function (_) {
{text: "Min of", value: 'min' },
{text: "Extended Stats", value: 'extended_stats' },
{text: "Percentiles", value: 'percentiles' },
+ {text: "Unique Count", value: "cardinality" }
],
bucketAggTypes: [
@@ -41,6 +42,17 @@ function (_) {
{text: "20", value: '20' },
],
+ extendedStats: [
+ {text: 'Avg', value: 'avg'},
+ {text: 'Min', value: 'min'},
+ {text: 'Max', value: 'max'},
+ {text: 'Sum', value: 'sum'},
+ {text: 'Count', value: 'count'},
+ {text: 'Std Dev', value: 'std_deviation'},
+ {text: 'Std Dev Upper', value: 'std_deviation_bounds_upper'},
+ {text: 'Std Dev Lower', value: 'std_deviation_bounds_lower'},
+ ],
+
getOrderByOptions: function(target) {
var self = this;
var metricRefs = [];
diff --git a/public/test/specs/elasticsearch-response-specs.js b/public/test/specs/elasticsearch-response-specs.js
new file mode 100644
index 00000000000..daf4cc126b8
--- /dev/null
+++ b/public/test/specs/elasticsearch-response-specs.js
@@ -0,0 +1,239 @@
+define([
+ 'plugins/datasource/elasticsearch/elasticResponse',
+], function(ElasticResponse) {
+ 'use strict';
+
+ describe('ElasticResponse', function() {
+ var targets;
+ var response;
+ var result;
+
+ describe('simple query and count', function() {
+
+ beforeEach(function() {
+ targets = [{
+ refId: 'A',
+ metrics: [{type: 'count', id: '1'}],
+ bucketAggs: [{type: 'date_histogram', field: '@timestamp', id: '2'}],
+ }];
+ response = {
+ responses: [{
+ aggregations: {
+ "2": {
+ buckets: [
+ {
+ doc_count: 10,
+ key: 1000
+ },
+ {
+ doc_count: 15,
+ key: 2000
+ }
+ ]
+ }
+ }
+ }]
+ };
+
+ result = new ElasticResponse(targets, response).getTimeSeries();
+ });
+
+ it('should return 1 series', function() {
+ expect(result.data.length).to.be(1);
+ expect(result.data[0].datapoints.length).to.be(2);
+ expect(result.data[0].datapoints[0][0]).to.be(10);
+ expect(result.data[0].datapoints[0][1]).to.be(1000);
+ });
+
+ });
+
+ describe('simple query count & avg aggregation', function() {
+ var result;
+
+ beforeEach(function() {
+ targets = [{
+ refId: 'A',
+ metrics: [{type: 'count', id: '1'}, {type: 'avg', field: 'value', id: '2'}],
+ bucketAggs: [{type: 'date_histogram', field: '@timestamp', id: '3'}],
+ }];
+ response = {
+ responses: [{
+ aggregations: {
+ "3": {
+ buckets: [
+ {
+ "2": {value: 88},
+ doc_count: 10,
+ key: 1000
+ },
+ {
+ "2": {value: 99},
+ doc_count: 15,
+ key: 2000
+ }
+ ]
+ }
+ }
+ }]
+ };
+
+ result = new ElasticResponse(targets, response).getTimeSeries();
+ });
+
+ it('should return 2 series', function() {
+ expect(result.data.length).to.be(2);
+ expect(result.data[0].datapoints.length).to.be(2);
+ expect(result.data[0].datapoints[0][0]).to.be(10);
+ expect(result.data[0].datapoints[0][1]).to.be(1000);
+
+ expect(result.data[1].target).to.be("A value avg");
+ expect(result.data[1].datapoints[0][0]).to.be(88);
+ expect(result.data[1].datapoints[1][0]).to.be(99);
+ });
+
+ });
+
+ describe('single group by query', function() {
+ var result;
+
+ beforeEach(function() {
+ targets = [{
+ refId: 'A',
+ metrics: [{type: 'count', id: '1'}],
+ bucketAggs: [{type: 'terms', field: 'host', id: '2'}, {type: 'date_histogram', field: '@timestamp', id: '3'}],
+ }];
+ response = {
+ responses: [{
+ aggregations: {
+ "2": {
+ buckets: [
+ {
+ "3": {
+ buckets: [
+ {doc_count: 1, key: 1000},
+ {doc_count: 3, key: 2000}
+ ]
+ },
+ doc_count: 4,
+ key: 'server1',
+ },
+ {
+ "3": {
+ buckets: [
+ {doc_count: 2, key: 1000},
+ {doc_count: 8, key: 2000}
+ ]
+ },
+ doc_count: 10,
+ key: 'server2',
+ },
+ ]
+ }
+ }
+ }]
+ };
+
+ result = new ElasticResponse(targets, response).getTimeSeries();
+ });
+
+ it('should return 2 series', function() {
+ expect(result.data.length).to.be(2);
+ expect(result.data[0].datapoints.length).to.be(2);
+ expect(result.data[0].target).to.be('A server1 count');
+ expect(result.data[1].target).to.be('A server2 count');
+ });
+ });
+
+ describe('with percentiles ', function() {
+ var result;
+
+ beforeEach(function() {
+ targets = [{
+ refId: 'A',
+ metrics: [{type: 'percentiles', settings: {percents: [75, 90]}, id: '1'}],
+ bucketAggs: [{type: 'date_histogram', field: '@timestamp', id: '3'}],
+ }];
+ response = {
+ responses: [{
+ aggregations: {
+ "3": {
+ buckets: [
+ {
+ "1": {values: {"75": 3.3, "90": 5.5}},
+ doc_count: 10,
+ key: 1000
+ },
+ {
+ "1": {values: {"75": 2.3, "90": 4.5}},
+ doc_count: 15,
+ key: 2000
+ }
+ ]
+ }
+ }
+ }]
+ };
+
+ result = new ElasticResponse(targets, response).getTimeSeries();
+ });
+
+ it('should return 2 series', function() {
+ expect(result.data.length).to.be(2);
+ expect(result.data[0].datapoints.length).to.be(2);
+ expect(result.data[0].target).to.be('A 75');
+ expect(result.data[1].target).to.be('A 90');
+ expect(result.data[0].datapoints[0][0]).to.be(3.3);
+ expect(result.data[0].datapoints[0][1]).to.be(1000);
+ expect(result.data[1].datapoints[1][0]).to.be(4.5);
+ });
+ });
+
+ describe('with extended_stats ', function() {
+ var result;
+
+ beforeEach(function() {
+ targets = [{
+ refId: 'A',
+ metrics: [{type: 'extended_stats', meta: {max: true, std_deviation_bounds_upper: true}, id: '1'}],
+ bucketAggs: [{type: 'date_histogram', id: '3'}],
+ }];
+ response = {
+ responses: [{
+ aggregations: {
+ "3": {
+ buckets: [
+ {
+ "1": {max: 10.2, min: 5.5, std_deviation_bounds: {upper: 3, lower: -2}},
+ doc_count: 10,
+ key: 1000
+ },
+ {
+ "1": {max: 7.2, min: 3.5, std_deviation_bounds: {upper: 4, lower: -1}},
+ doc_count: 15,
+ key: 2000
+ }
+ ]
+ }
+ }
+ }]
+ };
+
+ result = new ElasticResponse(targets, response).getTimeSeries();
+ });
+
+ it('should return 2 series', function() {
+ expect(result.data.length).to.be(2);
+ expect(result.data[0].datapoints.length).to.be(2);
+ expect(result.data[0].target).to.be('A max');
+ expect(result.data[1].target).to.be('A std_deviation_bounds_upper');
+
+ expect(result.data[0].datapoints[0][0]).to.be(10.2);
+ expect(result.data[0].datapoints[1][0]).to.be(7.2);
+
+ expect(result.data[1].datapoints[0][0]).to.be(3);
+ expect(result.data[1].datapoints[1][0]).to.be(4);
+ });
+ });
+
+ });
+});
diff --git a/public/test/specs/elasticsearch-specs.js b/public/test/specs/elasticsearch-specs.js
index 3fd4fd64773..3e6d2f4dd2c 100644
--- a/public/test/specs/elasticsearch-specs.js
+++ b/public/test/specs/elasticsearch-specs.js
@@ -3,7 +3,6 @@ define([
'moment',
'angular',
'plugins/datasource/elasticsearch/datasource',
- 'aws-sdk',
], function(helpers, moment, angular) {
'use strict';
@@ -18,7 +17,7 @@ define([
});
describe('When testing datasource with index pattern', function() {
- beforeEach(function(){
+ beforeEach(function() {
ctx.ds = new ctx.service({
url: 'http://es.com',
index: '[asd-]YYYY.MM.DD',
@@ -70,180 +69,9 @@ define([
var header = angular.fromJson(parts[0]);
expect(header.index).to.eql(['asd-2015.05.30', 'asd-2015.05.31', 'asd-2015.06.01']);
});
- });
-
- describe('When processing es response', function() {
-
- describe('simple query and count', function() {
- var result;
-
- beforeEach(function() {
- result = ctx.ds._processTimeSeries([{
- refId: 'A',
- metrics: [{type: 'count', id: '1'}],
- bucketAggs: [{type: 'date_histogram', field: '@timestamp', id: '2'}],
- }], {
- responses: [{
- aggregations: {
- "2": {
- buckets: [
- {
- doc_count: 10,
- key: 1000
- },
- {
- doc_count: 15,
- key: 2000
- }
- ]
- }
- }
- }]
- });
- });
-
- it('should return 1 series', function() {
- expect(result.data.length).to.be(1);
- expect(result.data[0].datapoints.length).to.be(2);
- expect(result.data[0].datapoints[0][0]).to.be(10);
- expect(result.data[0].datapoints[0][1]).to.be(1000);
- });
-
- });
-
- describe('simple query count & avg aggregation', function() {
- var result;
-
- beforeEach(function() {
- result = ctx.ds._processTimeSeries([{
- refId: 'A',
- metrics: [{type: 'count', id: '1'}, {type: 'avg', field: 'value', id: '2'}],
- bucketAggs: [{type: 'date_histogram', field: '@timestamp', id: '3'}],
- }], {
- responses: [{
- aggregations: {
- "3": {
- buckets: [
- {
- "2": {value: 88},
- doc_count: 10,
- key: 1000
- },
- {
- "2": {value: 99},
- doc_count: 15,
- key: 2000
- }
- ]
- }
- }
- }]
- });
- });
-
- it('should return 2 series', function() {
- expect(result.data.length).to.be(2);
- expect(result.data[0].datapoints.length).to.be(2);
- expect(result.data[0].datapoints[0][0]).to.be(10);
- expect(result.data[0].datapoints[0][1]).to.be(1000);
-
- expect(result.data[1].target).to.be("A value avg");
- expect(result.data[1].datapoints[0][0]).to.be(88);
- expect(result.data[1].datapoints[1][0]).to.be(99);
- });
-
- });
-
- describe('single group by query', function() {
- var result;
-
- beforeEach(function() {
- result = ctx.ds._processTimeSeries([{
- refId: 'A',
- metrics: [{type: 'count', id: '1'}],
- bucketAggs: [{type: 'terms', field: 'host', id: '2'}, {type: 'date_histogram', field: '@timestamp', id: '3'}],
- }], {
- responses: [{
- aggregations: {
- "2": {
- buckets: [
- {
- "3": {
- buckets: [
- {doc_count: 1, key: 1000},
- {doc_count: 3, key: 2000}
- ]
- },
- doc_count: 4,
- key: 'server1',
- },
- {
- "3": {
- buckets: [
- {doc_count: 2, key: 1000},
- {doc_count: 8, key: 2000}
- ]
- },
- doc_count: 10,
- key: 'server2',
- },
- ]
- }
- }
- }]
- });
- });
-
- it('should return 2 series', function() {
- expect(result.data.length).to.be(2);
- expect(result.data[0].datapoints.length).to.be(2);
- expect(result.data[0].target).to.be('A server1 count');
- expect(result.data[1].target).to.be('A server2 count');
- });
- });
-
- describe('with percentiles ', function() {
- var result;
-
- beforeEach(function() {
- result = ctx.ds._processTimeSeries([{
- refId: 'A',
- metrics: [{type: 'percentiles', settings: {percents: [75, 90]}, id: '1'}],
- bucketAggs: [{type: 'date_histogram', field: '@timestamp', id: '3'}],
- }], {
- responses: [{
- aggregations: {
- "3": {
- buckets: [
- {
- "1": {values: {"75": 3.3, "90": 5.5}},
- doc_count: 10,
- key: 1000
- },
- {
- "1": {values: {"75": 2.3, "90": 4.5}},
- doc_count: 15,
- key: 2000
- }
- ]
- }
- }
- }]
- });
- });
-
- it('should return 2 series', function() {
- expect(result.data.length).to.be(2);
- expect(result.data[0].datapoints.length).to.be(2);
- expect(result.data[0].target).to.be('A 75');
- expect(result.data[1].target).to.be('A 90');
- expect(result.data[0].datapoints[0][0]).to.be(3.3);
- expect(result.data[0].datapoints[0][1]).to.be(1000);
- expect(result.data[1].datapoints[1][0]).to.be(4.5);
- });
- });
-
});
+
});
+
});
diff --git a/public/test/test-main.js b/public/test/test-main.js
index ff5e64ab09b..6abf176b3e5 100644
--- a/public/test/test-main.js
+++ b/public/test/test-main.js
@@ -156,6 +156,7 @@ require([
'specs/elasticsearch-querybuilder-specs',
'specs/elasticsearch-queryctrl-specs',
'specs/elasticsearch-indexPattern-specs',
+ 'specs/elasticsearch-response-specs',
];
var pluginSpecs = (config.plugins.specs || []).map(function (spec) {