diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5470a86fb47..82b3ba2037e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,7 @@
* **InfluxDB**: Small fix for the "glow" when focus the field for LIMIT and SLIMIT [#7799](https://github.com/grafana/grafana/pull/7799) thx [@thuck](https://github.com/thuck)
* **Panels**: Delay loading & Lazy load panels as they become visible (scrolled into view) [#5216](https://github.com/grafana/grafana/issues/5216) thx [@jifwin](https://github.com/jifwin)
* **Graph**: Support auto grid min/max when using log scale [#3090](https://github.com/grafana/grafana/issues/3090), thx [@bigbenhur](https://github.com/bigbenhur)
+* **Elasticsearch**: Support histogram aggregations [#3164](https://github.com/grafana/grafana/issues/3164)
## Minor Enchancements
diff --git a/public/app/plugins/datasource/elasticsearch/bucket_agg.js b/public/app/plugins/datasource/elasticsearch/bucket_agg.js
index 28f1df08251..d6d641c1655 100644
--- a/public/app/plugins/datasource/elasticsearch/bucket_agg.js
+++ b/public/app/plugins/datasource/elasticsearch/bucket_agg.js
@@ -50,6 +50,7 @@ function (angular, _, queryDef) {
switch($scope.agg.type) {
case 'date_histogram':
+ case 'histogram':
case 'terms': {
delete $scope.agg.query;
$scope.agg.field = 'select field';
@@ -132,6 +133,16 @@ function (angular, _, queryDef) {
}
break;
}
+ case 'histogram': {
+ settings.interval = settings.interval || 1000;
+ settings.min_doc_count = _.defaultTo(settings.min_doc_count, 1);
+ settingsLinkText = 'Interval: ' + settings.interval;
+
+ if (settings.min_doc_count > 0) {
+ settingsLinkText += ', Min Doc Count: ' + settings.min_doc_count;
+ }
+ break;
+ }
case 'geohash_grid': {
// limit precision to 7
settings.precision = Math.max(Math.min(settings.precision, 7), 1);
diff --git a/public/app/plugins/datasource/elasticsearch/partials/bucket_agg.html b/public/app/plugins/datasource/elasticsearch/partials/bucket_agg.html
index 562f0b86e56..f1e650f6830 100644
--- a/public/app/plugins/datasource/elasticsearch/partials/bucket_agg.html
+++ b/public/app/plugins/datasource/elasticsearch/partials/bucket_agg.html
@@ -52,6 +52,17 @@
+
diff --git a/public/app/plugins/datasource/elasticsearch/query_builder.js b/public/app/plugins/datasource/elasticsearch/query_builder.js
index 11e8b69ddaa..808fea3cc70 100644
--- a/public/app/plugins/datasource/elasticsearch/query_builder.js
+++ b/public/app/plugins/datasource/elasticsearch/query_builder.js
@@ -79,6 +79,19 @@ function (queryDef) {
return esAgg;
};
+ ElasticQueryBuilder.prototype.getHistogramAgg = function(aggDef) {
+ var esAgg = {};
+ var settings = aggDef.settings || {};
+ esAgg.interval = settings.interval;
+ esAgg.field = aggDef.field;
+ esAgg.min_doc_count = settings.min_doc_count || 0;
+
+ if (settings.missing) {
+ esAgg.missing = settings.missing;
+ }
+ return esAgg;
+ };
+
ElasticQueryBuilder.prototype.getFiltersAgg = function(aggDef) {
var filterObj = {};
for (var i = 0; i < aggDef.settings.filters.length; i++) {
@@ -192,6 +205,10 @@ function (queryDef) {
esAgg["date_histogram"] = this.getDateHistogramAgg(aggDef);
break;
}
+ case 'histogram': {
+ esAgg["histogram"] = this.getHistogramAgg(aggDef);
+ break;
+ }
case 'filters': {
esAgg["filters"] = {filters: this.getFiltersAgg(aggDef)};
break;
diff --git a/public/app/plugins/datasource/elasticsearch/query_def.js b/public/app/plugins/datasource/elasticsearch/query_def.js
index 5afc908edba..a55e2dfd9e5 100644
--- a/public/app/plugins/datasource/elasticsearch/query_def.js
+++ b/public/app/plugins/datasource/elasticsearch/query_def.js
@@ -24,6 +24,7 @@ function (_) {
{text: "Filters", value: 'filters' },
{text: "Geo Hash Grid", value: 'geohash_grid', requiresField: true},
{text: "Date Histogram", value: 'date_histogram', requiresField: true},
+ {text: "Histogram", value: 'histogram', requiresField: true},
],
orderByOptions: [
diff --git a/public/app/plugins/datasource/elasticsearch/specs/elastic_response_specs.ts b/public/app/plugins/datasource/elasticsearch/specs/elastic_response_specs.ts
index 4b87cc52c04..589e0ccbfab 100644
--- a/public/app/plugins/datasource/elasticsearch/specs/elastic_response_specs.ts
+++ b/public/app/plugins/datasource/elasticsearch/specs/elastic_response_specs.ts
@@ -361,6 +361,39 @@ describe('ElasticResponse', function() {
});
});
+ describe('histogram response', function() {
+ var result;
+
+ beforeEach(function() {
+ targets = [{
+ refId: 'A',
+ metrics: [{type: 'count', id: '1'}],
+ bucketAggs: [{type: 'histogram', field: 'bytes', id: '3'}],
+ }];
+ response = {
+ responses: [{
+ aggregations: {
+ "3": {
+ buckets: [
+ {doc_count: 1, key: 1000},
+ {doc_count: 3, key: 2000},
+ {doc_count: 2, key: 1000},
+ ]
+ }
+ }
+ }]
+ };
+
+ result = new ElasticResponse(targets, response).getTimeSeries();
+ });
+
+ it('should return docs with byte and count', function() {
+ expect(result.data[0].datapoints.length).to.be(3);
+ expect(result.data[0].datapoints[0].Count).to.be(1);
+ expect(result.data[0].datapoints[0].bytes).to.be(1000);
+ });
+ });
+
describe('with two filters agg', function() {
var result;
diff --git a/public/app/plugins/datasource/elasticsearch/specs/query_builder_specs.ts b/public/app/plugins/datasource/elasticsearch/specs/query_builder_specs.ts
index e60cde7a163..18645ad498d 100644
--- a/public/app/plugins/datasource/elasticsearch/specs/query_builder_specs.ts
+++ b/public/app/plugins/datasource/elasticsearch/specs/query_builder_specs.ts
@@ -249,6 +249,23 @@ describe('ElasticQueryBuilder', function() {
expect(firstLevel.aggs["2"].derivative.buckets_path).to.be("3");
});
+ it('with histogram', function() {
+ var query = builder.build({
+ metrics: [
+ {id: '1', type: 'count' },
+ ],
+ bucketAggs: [
+ {type: 'histogram', field: 'bytes', id: '3', settings: {interval: 10, min_doc_count: 2, missing: 5}}
+ ],
+ });
+
+ var firstLevel = query.aggs["3"];
+ expect(firstLevel.histogram.field).to.be('bytes');
+ expect(firstLevel.histogram.interval).to.be(10);
+ expect(firstLevel.histogram.min_doc_count).to.be(2);
+ expect(firstLevel.histogram.missing).to.be(5);
+ });
+
it('with adhoc filters', function() {
var query = builder.build({
metrics: [{type: 'Count', id: '0'}],