Commit f1e995ec by Torkel Ödegaard

feat(elasticsearch): added bucket agg id concept

parent 756ec8cc
......@@ -65,7 +65,7 @@ function (angular, _, $) {
$scope.orderByOptions = [
{text: "Doc Count", value: '_count' },
{text: "Term name", value: '_term' },
{text: "Average of @value", value: '0' },
{text: "Average of @value", value: 'm0' },
];
}
......@@ -78,7 +78,11 @@ function (angular, _, $) {
addIndex - 1;
}
bucketAggs.splice(addIndex, 0, {type: "terms", field: "select field" });
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.removeBucketAgg = function() {
......
......@@ -174,18 +174,19 @@ function (angular, _, config, kbn, moment, ElasticQueryBuilder) {
// This is quite complex
// neeed to recurise down the nested buckets to build series
ElasticDatasource.prototype._processBuckets = function(buckets, target, series, level, parentName) {
var seriesName, value, metric, i, y, bucket, childBucket;
ElasticDatasource.prototype._processBuckets = function(aggs, target, series, level, parentName) {
var seriesName, value, metric, i, y, bucket, childBucket, aggDef, esAgg;
var buckets;
var dataFound = 0;
for (i = 0; i < buckets.length; i++) {
bucket = buckets[i];
childBucket = bucket['b' + level];
aggDef = target.bucketAggs[level];
esAgg = aggs[aggDef.id];
if (childBucket && childBucket.buckets) {
seriesName = parentName + ' ' + bucket.key;
this._processBuckets(childBucket.buckets, target, series, level+1, seriesName);
} else {
for (i = 0; i < esAgg.buckets.length; i++) {
bucket = esAgg.buckets[i];
// if last agg collect series
if (level === target.bucketAggs.length - 1) {
for (y = 0; y < target.metrics.length; y++) {
metric = target.metrics[y];
seriesName = parentName;
......@@ -195,13 +196,16 @@ function (angular, _, config, kbn, moment, ElasticQueryBuilder) {
value = bucket.doc_count;
} else {
seriesName += ' ' + metric.field + ' ' + metric.type;
value = bucket['m' + y.toString()].value;
value = bucket[metric.id].value;
}
var serie = series[seriesName] = series[seriesName] || {target: seriesName, datapoints: []};
serie.datapoints.push([value, bucket.key]);
}
}
else {
this._processBuckets(bucket, target, series, level+1, parentName + ' ' + bucket.key);
}
}
};
......@@ -214,11 +218,11 @@ function (angular, _, config, kbn, moment, ElasticQueryBuilder) {
throw { message: response.error };
}
var buckets = response.aggregations["b0"].buckets;
var aggregations = response.aggregations;
var target = targets[i];
var querySeries = {};
this._processBuckets(buckets, target, querySeries, 1, target.refId);
this._processBuckets(aggregations, target, querySeries, 0, target.refId);
for (var prop in querySeries) {
if (querySeries.hasOwnProperty(prop)) {
......
......@@ -39,7 +39,12 @@ function (angular, _, $) {
$scope.addMetricAgg = function() {
var addIndex = metricAggs.length;
metricAggs.splice(addIndex, 0, {type: "count", field: "select field" });
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()});
};
$scope.removeMetricAgg = function() {
......
......@@ -54,13 +54,19 @@ function (angular) {
break;
}
case 'terms': {
esAgg["terms"] = { "field": aggDef.field };
esAgg.terms = { "field": aggDef.field };
var size = parseInt(aggDef.size, 10);
if (size > 0) { esAgg.terms.size = size; }
if (aggDef.orderBy) {
esAgg.terms.order = {};
esAgg.terms.order[aggDef.orderBy] = aggDef.order;
}
break;
}
}
nestedAggs.aggs = {};
nestedAggs.aggs['b' + i] = esAgg;
nestedAggs.aggs[aggDef.id] = esAgg;
nestedAggs = esAgg;
}
......@@ -74,7 +80,7 @@ function (angular) {
var aggField = {};
aggField[metric.type] = {field: metric.field};
nestedAggs.aggs['m' + i] = aggField;
nestedAggs.aggs[metric.id] = aggField;
}
return query;
......
......@@ -15,16 +15,18 @@ function (angular, _, ElasticQueryBuilder) {
if (!target) { return; }
target.timeField = target.timeField || '@timestamp';
target.metrics = target.metrics || [{ type: 'count' }];
target.metrics = target.metrics || [{ type: 'count', id: '1' }];
target.bucketAggs = target.bucketAggs || [];
target.bucketAggs = [
{
type: 'terms',
field: '@hostname'
field: '@hostname',
id: '2'
},
{
type: 'date_histogram',
field: '@timestamp'
field: '@timestamp',
id: '3'
},
];
......
......@@ -9,29 +9,29 @@ define([
var builder = new ElasticQueryBuilder();
var query = builder.build({
metrics: [{type: 'Count'}],
metrics: [{type: 'Count', id: '0'}],
timeField: '@timestamp',
bucketAggs: [{type: 'date_histogram', field: '@timestamp'}],
bucketAggs: [{type: 'date_histogram', field: '@timestamp', id: '1'}],
});
expect(query.query.filtered.filter.bool.must[0].range["@timestamp"].gte).to.be("$timeFrom");
expect(query.aggs["b0"].date_histogram.extended_bounds.min).to.be("$timeFrom");
expect(query.aggs["1"].date_histogram.extended_bounds.min).to.be("$timeFrom");
});
it('with multiple bucket aggs', function() {
var builder = new ElasticQueryBuilder();
var query = builder.build({
metrics: [{type: 'Count'}],
metrics: [{type: 'count', id: '1'}],
timeField: '@timestamp',
bucketAggs: [
{type: 'terms', field: '@host'},
{type: 'date_histogram', field: '@timestamp'}
{type: 'terms', field: '@host', id: '2'},
{type: 'date_histogram', field: '@timestamp', id: '3'}
],
});
expect(query.aggs["b0"].terms.field).to.be("@host");
expect(query.aggs["b0"].aggs["b1"].date_histogram.field).to.be("@timestamp");
expect(query.aggs["2"].terms.field).to.be("@host");
expect(query.aggs["2"].aggs["3"].date_histogram.field).to.be("@timestamp");
});
......@@ -39,14 +39,31 @@ define([
var builder = new ElasticQueryBuilder();
var query = builder.build({
metrics: [{type: 'avg', field: '@value'}],
bucketAggs: [{type: 'date_histogram', field: '@timestamp'}],
metrics: [{type: 'avg', field: '@value', id: '1'}],
bucketAggs: [{type: 'date_histogram', field: '@timestamp', id: '2'}],
}, 100, 1000);
var aggs = query.aggs["b0"].aggs;
expect(aggs["m0"].avg.field).to.be("@value");
var aggs = query.aggs["2"].aggs;
expect(aggs["1"].avg.field).to.be("@value");
});
it('with term agg and order by metric agg', function() {
var builder = new ElasticQueryBuilder();
var query = builder.build({
metrics: [{type: 'avg', field: '@value', id: '1'}],
bucketAggs: [
{type: 'term', size: 5, order: 'asc', orderBy: 'm0', id: '2' },
{type: 'date_histogram', field: '@timestamp', id: '3'}
],
}, 100, 1000);
var firstLevel = query.aggs["2"];
var secondLevel = firstLevel.aggs["3"];
// expect(firstLevel.aggs["m0"].avg.field).to.be("@value");
expect(secondLevel.aggs["1"].avg.field).to.be("@value");
});
});
......
......@@ -26,27 +26,6 @@ define([
ctx.scope.init();
});
it('should init selectSegments', function() {
expect(ctx.scope.selectSegments.length).to.be(2);
});
describe('initSelectSegments with 2 selects', function() {
it('init selectSegments', function() {
ctx.scope.target.metrics = [
{agg: 'count'},
{agg: 'avg', field: 'value'},
];
ctx.scope.initSelectSegments();
expect(ctx.scope.selectSegments.length).to.be(5);
expect(ctx.scope.selectSegments[0].value).to.be('count');
expect(ctx.scope.selectSegments[1].value).to.be(' and ');
expect(ctx.scope.selectSegments[2].value).to.be('avg');
expect(ctx.scope.selectSegments[3].value).to.be('value');
});
});
});
});
......
......@@ -23,12 +23,12 @@ define([
beforeEach(function() {
result = ctx.ds._processTimeSeries([{
refId: 'A',
metrics: [{agg: 'count'}],
bucketAggs: [{type: 'date_histogram', field: '@timestamp'}],
metrics: [{type: 'count', id: '1'}],
bucketAggs: [{type: 'date_histogram', field: '@timestamp', id: '2'}],
}], {
responses: [{
aggregations: {
"b0": {
"2": {
buckets: [
{
doc_count: 10,
......@@ -60,20 +60,20 @@ define([
beforeEach(function() {
result = ctx.ds._processTimeSeries([{
refId: 'A',
metrics: [{agg: 'count'}, {agg: 'avg', field: 'value'}],
bucketAggs: [{type: 'date_histogram', field: '@timestamp'}],
metrics: [{type: 'count', id: '1'}, {type: 'avg', field: 'value', id: '2'}],
bucketAggs: [{type: 'date_histogram', field: '@timestamp', id: '3'}],
}], {
responses: [{
aggregations: {
"b0": {
"3": {
buckets: [
{
"m1": {value: 88},
"2": {value: 88},
doc_count: 10,
key: 1000
},
{
"m1": {value: 99},
"2": {value: 99},
doc_count: 15,
key: 2000
}
......@@ -103,15 +103,15 @@ define([
beforeEach(function() {
result = ctx.ds._processTimeSeries([{
refId: 'A',
metrics: [{agg: 'count'}],
bucketAggs: [{type: 'terms', field: 'host'}, {type: 'date_histogram', field: '@timestamp'}],
metrics: [{type: 'count', id: '1'}],
bucketAggs: [{type: 'terms', field: 'host', id: '2'}, {type: 'date_histogram', field: '@timestamp', id: '3'}],
}], {
responses: [{
aggregations: {
"b0": {
"2": {
buckets: [
{
"b1": {
"3": {
buckets: [
{doc_count: 1, key: 1000},
{doc_count: 3, key: 2000}
......@@ -121,7 +121,7 @@ define([
key: 'server1',
},
{
"b1": {
"3": {
buckets: [
{doc_count: 2, key: 1000},
{doc_count: 8, key: 2000}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment