Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sum, Avg, Min and Max bucket pipeline aggregation #10070

Merged
merged 10 commits into from
Mar 1, 2017
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@
ng-model="agg.type"
required
auto-select-if-only-one="aggTypeOptions | aggFilter:agg.schema.aggFilter"
ng-options="agg as agg.title for agg in aggTypeOptions | aggFilter:agg.schema.aggFilter">
ng-options="agg as agg.title group by agg.subtype for agg in aggTypeOptions | aggFilter:agg.schema.aggFilter">
</select>
</div>
110 changes: 110 additions & 0 deletions src/ui/public/agg_types/__tests__/metrics/sibling_pipeline.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import _ from 'lodash';
import expect from 'expect.js';
import ngMock from 'ng_mock';
import BucketSum from 'ui/agg_types/metrics/bucket_sum';
import BucketAvg from 'ui/agg_types/metrics/bucket_avg';
import BucketMin from 'ui/agg_types/metrics/bucket_min';
import BucketMax from 'ui/agg_types/metrics/bucket_max';
import VisProvider from 'ui/vis';
import StubbedIndexPattern from 'fixtures/stubbed_logstash_index_pattern';

const metrics = [
{ name: 'sum_bucket', title: 'Overall Sum', provider: BucketSum },
{ name: 'avg_bucket', title: 'Overall Average', provider: BucketAvg },
{ name: 'min_bucket', title: 'Overall Min', provider: BucketMin },
{ name: 'max_bucket', title: 'Overall Max', provider: BucketMax },
];

describe('sibling pipeline aggs', function () {
metrics.forEach(metric => {
describe(`${metric.title} metric`, function () {

let aggDsl;
let metricAgg;
let aggConfig;

function init(settings) {
ngMock.module('kibana');
ngMock.inject(function (Private) {
const Vis = Private(VisProvider);
const indexPattern = Private(StubbedIndexPattern);
metricAgg = Private(metric.provider);

const params = settings || {
customMetric: {
id: '5',
type: 'count',
schema: 'metric'
},
customBucket: {
id: '6',
type: 'date_histogram',
schema: 'bucket',
params: { field: '@timestamp' }
}
};

const vis = new Vis(indexPattern, {
title: 'New Visualization',
type: 'metric',
params: {
fontSize: 60,
handleNoResults: true
},
aggs: [
{
id: '1',
type: 'count',
schema: 'metric'
},
{
id: '2',
type: metric.name,
schema: 'metric',
params
}
],
listeners: {}
});

// Grab the aggConfig off the vis (we don't actually use the vis for anything else)
aggConfig = vis.aggs[1];
aggDsl = aggConfig.toDsl();
});
}

it(`should return a label prefixed with ${metric.title} of`, function () {
init();
expect(metricAgg.makeLabel(aggConfig)).to.eql(`${metric.title} of Count`);
});

it('should set parent aggs', function () {
init();
expect(aggDsl[metric.name].buckets_path).to.be('2-bucket>_count');
expect(aggDsl.parentAggs['2-bucket'].date_histogram).to.not.be.undefined;
});

it('should set nested parent aggs', function () {
init({
customMetric: {
id: '5',
type: 'avg',
schema: 'metric',
params: { field: 'bytes' },
},
customBucket: {
id: '6',
type: 'date_histogram',
schema: 'bucket',
params: { field: '@timestamp' },
}
});
expect(aggDsl[metric.name].buckets_path).to.be('2-bucket>2-metric');
expect(aggDsl.parentAggs['2-bucket'].date_histogram).to.not.be.undefined;
expect(aggDsl.parentAggs['2-bucket'].aggs['2-metric'].avg.field).to.equal('bytes');
});

});
});

});
4 changes: 3 additions & 1 deletion src/ui/public/agg_types/buckets/terms.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@ export default function TermsAggDefinition(Private) {

const aggFilter = [
'!top_hits', '!percentiles', '!median', '!std_dev',
'!derivative', '!cumulative_sum', '!moving_avg', '!serial_diff'
'!derivative', '!moving_avg', '!serial_diff', '!cumulative_sum',
'!avg_bucket', '!max_bucket', '!min_bucket', '!sum_bucket'
];

const orderAggSchema = (new Schemas([
{
group: 'none',
Expand Down
14 changes: 14 additions & 0 deletions src/ui/public/agg_types/controls/sub_metric.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<div ng-controller="aggParam.controller">
<div class="form-group" ng-if="agg.params[aggType]">
<label>{{aggTitle}}</label>
<div class="vis-editor-agg-order-agg">
<ng-form name="{{aggType}}Form">
<vis-editor-agg-params
agg="agg.params[aggType]"
group-name="'{{aggGroup}}'">
</vis-editor-agg-params>
</ng-form>
</div>
</div>

</div>
10 changes: 9 additions & 1 deletion src/ui/public/agg_types/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ import AggTypesBucketsTermsProvider from 'ui/agg_types/buckets/terms';
import AggTypesBucketsFiltersProvider from 'ui/agg_types/buckets/filters';
import AggTypesBucketsSignificantTermsProvider from 'ui/agg_types/buckets/significant_terms';
import AggTypesBucketsGeoHashProvider from 'ui/agg_types/buckets/geo_hash';
import AggTypesMetricsBucketSumProvider from 'ui/agg_types/metrics/bucket_sum';
import AggTypesMetricsBucketAvgProvider from 'ui/agg_types/metrics/bucket_avg';
import AggTypesMetricsBucketMinProvider from 'ui/agg_types/metrics/bucket_min';
import AggTypesMetricsBucketMaxProvider from 'ui/agg_types/metrics/bucket_max';
export default function AggTypeService(Private) {

const aggs = {
Expand All @@ -42,7 +46,11 @@ export default function AggTypeService(Private) {
Private(AggTypesMetricsDerivativeProvider),
Private(AggTypesMetricsCumulativeSumProvider),
Private(AggTypesMetricsMovingAvgProvider),
Private(AggTypesMetricsSerialDiffProvider)
Private(AggTypesMetricsSerialDiffProvider),
Private(AggTypesMetricsBucketAvgProvider),
Private(AggTypesMetricsBucketSumProvider),
Private(AggTypesMetricsBucketMinProvider),
Private(AggTypesMetricsBucketMaxProvider),
],
buckets: [
Private(AggTypesBucketsDateHistogramProvider),
Expand Down
18 changes: 18 additions & 0 deletions src/ui/public/agg_types/metrics/bucket_avg.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import AggTypesMetricsMetricAggTypeProvider from 'ui/agg_types/metrics/metric_agg_type';
import { makeNestedLabel } from './lib/make_nested_label';
import SiblingPipelineAggHelperProvider from './lib/sibling_pipeline_agg_helper';

export default function AggTypesMetricsBucketAvgProvider(Private) {
const MetricAggType = Private(AggTypesMetricsMetricAggTypeProvider);
const siblingPipelineHelper = Private(SiblingPipelineAggHelperProvider);

return new MetricAggType({
name: 'avg_bucket',
title: 'Average Bucket',
makeLabel: agg => makeNestedLabel(agg, 'overall average'),
subtype: siblingPipelineHelper.subtype,
params: [
...siblingPipelineHelper.params()
]
});
}
18 changes: 18 additions & 0 deletions src/ui/public/agg_types/metrics/bucket_max.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import AggTypesMetricsMetricAggTypeProvider from 'ui/agg_types/metrics/metric_agg_type';
import { makeNestedLabel } from './lib/make_nested_label';
import SiblingPipelineAggHelperProvider from './lib/sibling_pipeline_agg_helper';

export default function AggTypesMetricsBucketMaxProvider(Private) {
const MetricAggType = Private(AggTypesMetricsMetricAggTypeProvider);
const siblingPipelineHelper = Private(SiblingPipelineAggHelperProvider);

return new MetricAggType({
name: 'max_bucket',
title: 'Max Bucket',
makeLabel: agg => makeNestedLabel(agg, 'overall max'),
subtype: siblingPipelineHelper.subtype,
params: [
...siblingPipelineHelper.params()
]
});
}
18 changes: 18 additions & 0 deletions src/ui/public/agg_types/metrics/bucket_min.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import AggTypesMetricsMetricAggTypeProvider from 'ui/agg_types/metrics/metric_agg_type';
import { makeNestedLabel } from './lib/make_nested_label';
import SiblingPipelineAggHelperProvider from './lib/sibling_pipeline_agg_helper';

export default function AggTypesMetricsBucketMinProvider(Private) {
const MetricAggType = Private(AggTypesMetricsMetricAggTypeProvider);
const siblingPipelineHelper = Private(SiblingPipelineAggHelperProvider);

return new MetricAggType({
name: 'min_bucket',
title: 'Min Bucket',
makeLabel: agg => makeNestedLabel(agg, 'overall min'),
subtype: siblingPipelineHelper.subtype,
params: [
...siblingPipelineHelper.params()
]
});
}
18 changes: 18 additions & 0 deletions src/ui/public/agg_types/metrics/bucket_sum.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import AggTypesMetricsMetricAggTypeProvider from 'ui/agg_types/metrics/metric_agg_type';
import { makeNestedLabel } from './lib/make_nested_label';
import SiblingPipelineAggHelperProvider from './lib/sibling_pipeline_agg_helper';

export default function AggTypesMetricsBucketSumProvider(Private) {
const MetricAggType = Private(AggTypesMetricsMetricAggTypeProvider);
const siblingPipelineHelper = Private(SiblingPipelineAggHelperProvider);

return new MetricAggType({
name: 'sum_bucket',
title: 'Sum Bucket',
makeLabel: agg => makeNestedLabel(agg, 'overall sum'),
subtype: siblingPipelineHelper.subtype,
params: [
...siblingPipelineHelper.params()
]
});
}
1 change: 1 addition & 0 deletions src/ui/public/agg_types/metrics/cumulative_sum.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export default function AggTypeMetricComulativeSumProvider(Private) {
return new MetricAggType({
name: 'cumulative_sum',
title: 'Cumulative Sum',
subtype: parentPipelineAggHelper.subtype,
makeLabel: agg => makeNestedLabel(agg, 'cumulative sum'),
params: [
...parentPipelineAggHelper.params()
Expand Down
1 change: 1 addition & 0 deletions src/ui/public/agg_types/metrics/derivative.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export default function AggTypeMetricDerivativeProvider(Private) {
return new MetricAggType({
name: 'derivative',
title: 'Derivative',
subtype: parentPipelineAggHelper.subtype,
makeLabel: agg => makeNestedLabel(agg, 'derivative'),
params: [
...parentPipelineAggHelper.params()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ const ParentPipelineAggHelperProvider = function (Private) {
])).all[0];

return {
subtype: 'Parent Pipeline Aggregations',
params: function () {
return [
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import safeMakeLabel from './safe_make_label';

const siblingPipelineAggController = function (type) {
return function ($scope) {

$scope.aggType = type;
$scope.aggTitle = type === 'customMetric' ? 'Metric' : 'Bucket';
$scope.aggGroup = type === 'customMetric' ? 'metrics' : 'buckets';
$scope.safeMakeLabel = safeMakeLabel;

function updateAgg() {
const agg = $scope.agg;
const params = agg.params;
const paramDef = agg.type.params.byName[type];

params[type] = params[type] || paramDef.makeAgg(agg);
}

updateAgg();
};
};

export { siblingPipelineAggController };
92 changes: 92 additions & 0 deletions src/ui/public/agg_types/metrics/lib/sibling_pipeline_agg_helper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import _ from 'lodash';
import VisAggConfigProvider from 'ui/vis/agg_config';
import VisSchemasProvider from 'ui/vis/schemas';

import { siblingPipelineAggController } from './sibling_pipeline_agg_controller';
import { siblingPipelineAggWritter } from './sibling_pipeline_agg_writter';
import metricAggTemplate from 'ui/agg_types/controls/sub_metric.html';

const SiblingPipelineAggHelperProvider = function (Private) {

const AggConfig = Private(VisAggConfigProvider);
const Schemas = Private(VisSchemasProvider);

const metricAggFilter = [
'!top_hits', '!percentiles', '!percentile_ranks', '!median', '!std_dev',
'!sum_bucket', '!avg_bucket', '!min_bucket', '!max_bucket',
'!derivative', '!moving_avg', '!serial_diff', '!cumulative_sum'
];

const metricAggSchema = (new Schemas([
{
group: 'none',
name: 'metricAgg',
title: 'Metric Agg',
aggFilter: metricAggFilter
}
])).all[0];

const bucketAggFilter = [];
const bucketAggSchema = (new Schemas([
{
group: 'none',
title: 'Bucket Agg',
name: 'bucketAgg',
aggFilter: bucketAggFilter
}
])).all[0];

return {
subtype: 'Sibling Pipeline Aggregations',
params: function () {
return [
{
name: 'customBucket',
type: AggConfig,
default: null,
serialize: function (customMetric) {
return customMetric.toJSON();
},
deserialize: function (state, agg) {
return this.makeAgg(agg, state);
},
makeAgg: function (agg, state) {
state = state || { type: 'date_histogram' };
state.schema = bucketAggSchema;
const orderAgg = new AggConfig(agg.vis, state);
orderAgg.id = agg.id + '-bucket';
return orderAgg;
},
editor: metricAggTemplate,
controller: siblingPipelineAggController('customBucket'),
write: _.noop
},
{
name: 'customMetric',
type: AggConfig,
default: null,
serialize: function (customMetric) {
return customMetric.toJSON();
},
deserialize: function (state, agg) {
return this.makeAgg(agg, state);
},
makeAgg: function (agg, state) {
state = state || { type: 'count' };
state.schema = metricAggSchema;
const orderAgg = new AggConfig(agg.vis, state);
orderAgg.id = agg.id + '-metric';
return orderAgg;
},
editor: metricAggTemplate,
controller: siblingPipelineAggController('customMetric'),
write: siblingPipelineAggWritter
}
];
}
};


};

export default SiblingPipelineAggHelperProvider;
Loading