Skip to content

Commit

Permalink
Allow sorting by median (elastic#79839)
Browse files Browse the repository at this point in the history
  • Loading branch information
flash1293 committed Oct 14, 2020
1 parent 32c99db commit fe53f2b
Show file tree
Hide file tree
Showing 10 changed files with 94 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) &gt; [AggConfig](./kibana-plugin-plugins-data-public.aggconfig.md) &gt; [getValueBucketPath](./kibana-plugin-plugins-data-public.aggconfig.getvaluebucketpath.md)

## AggConfig.getValueBucketPath() method

Returns the bucket path containing the main value the agg will produce (e.g. for sum of bytes it will point to the sum, for median it will point to the 50 percentile in the percentile multi value bucket)

<b>Signature:</b>

```typescript
getValueBucketPath(): string;
```
<b>Returns:</b>

`string`

Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ export declare class AggConfig
| [getResponseAggs()](./kibana-plugin-plugins-data-public.aggconfig.getresponseaggs.md) | | |
| [getTimeRange()](./kibana-plugin-plugins-data-public.aggconfig.gettimerange.md) | | |
| [getValue(bucket)](./kibana-plugin-plugins-data-public.aggconfig.getvalue.md) | | |
| [getValueBucketPath()](./kibana-plugin-plugins-data-public.aggconfig.getvaluebucketpath.md) | | Returns the bucket path containing the main value the agg will produce (e.g. for sum of bytes it will point to the sum, for median it will point to the 50 percentile in the percentile multi value bucket) |
| [isFilterable()](./kibana-plugin-plugins-data-public.aggconfig.isfilterable.md) | | |
| [makeLabel(percentageMode)](./kibana-plugin-plugins-data-public.aggconfig.makelabel.md) | | |
| [nextId(list)](./kibana-plugin-plugins-data-public.aggconfig.nextid.md) | <code>static</code> | Calculate the next id based on the ids in this list {<!-- -->array<!-- -->} list - a list of objects with id properties |
Expand Down
9 changes: 9 additions & 0 deletions src/plugins/data/common/search/aggs/agg_config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,15 @@ export class AggConfig {
return this.params.field;
}

/**
* Returns the bucket path containing the main value the agg will produce
* (e.g. for sum of bytes it will point to the sum, for median it will point
* to the 50 percentile in the percentile multi value bucket)
*/
getValueBucketPath() {
return this.type.getValueBucketPath(this);
}

makeLabel(percentageMode = false) {
if (this.params.customLabel) {
return this.params.customLabel;
Expand Down
9 changes: 9 additions & 0 deletions src/plugins/data/common/search/aggs/agg_type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ export interface AggTypeConfig<
getSerializedFormat?: (agg: TAggConfig) => SerializedFieldFormat;
getValue?: (agg: TAggConfig, bucket: any) => any;
getKey?: (bucket: any, key: any, agg: TAggConfig) => any;
getValueBucketPath?: (agg: TAggConfig) => string;
}

// TODO need to make a more explicit interface for this
Expand Down Expand Up @@ -210,6 +211,10 @@ export class AggType<
return this.params.find((p: TParam) => p.name === name);
};

getValueBucketPath = (agg: TAggConfig) => {
return agg.id;
};

/**
* Generic AggType Constructor
*
Expand All @@ -233,6 +238,10 @@ export class AggType<
this.createFilter = config.createFilter;
}

if (config.getValueBucketPath) {
this.getValueBucketPath = config.getValueBucketPath;
}

if (config.params && config.params.length && config.params[0] instanceof BaseParamType) {
this.params = config.params as TParam[];
} else {
Expand Down
45 changes: 45 additions & 0 deletions src/plugins/data/common/search/aggs/buckets/terms.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
*/

import { AggConfigs } from '../agg_configs';
import { METRIC_TYPES } from '../metrics';
import { mockAggTypesRegistry } from '../test_helpers';
import { BUCKET_TYPES } from './bucket_agg_types';

Expand Down Expand Up @@ -133,5 +134,49 @@ describe('Terms Agg', () => {
expect(params.include).toStrictEqual([1.1, 2, 3.33]);
expect(params.exclude).toStrictEqual([4, 5.555, 6]);
});

test('uses correct bucket path for sorting by median', () => {
const indexPattern = {
id: '1234',
title: 'logstash-*',
fields: {
getByName: () => field,
filter: () => [field],
},
} as any;

const field = {
name: 'field',
indexPattern,
};

const aggConfigs = new AggConfigs(
indexPattern,
[
{
id: 'test',
params: {
field: {
name: 'string_field',
type: 'string',
},
orderAgg: {
type: METRIC_TYPES.MEDIAN,
params: {
field: {
name: 'number_field',
type: 'number',
},
},
},
},
type: BUCKET_TYPES.TERMS,
},
],
{ typesRegistry: mockAggTypesRegistry() }
);
const { [BUCKET_TYPES.TERMS]: params } = aggConfigs.aggs[0].toDsl();
expect(params.order).toEqual({ 'test-orderAgg.50': 'desc' });
});
});
});
5 changes: 2 additions & 3 deletions src/plugins/data/common/search/aggs/buckets/terms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ import {
export const termsAggFilter = [
'!top_hits',
'!percentiles',
'!median',
'!std_dev',
'!derivative',
'!moving_avg',
Expand Down Expand Up @@ -198,14 +197,14 @@ export const getTermsBucketAgg = () =>
return;
}

const orderAggId = orderAgg.id;
const orderAggPath = orderAgg.getValueBucketPath();

if (orderAgg.parentId && aggs) {
orderAgg = aggs.byId(orderAgg.parentId);
}

output.subAggs = (output.subAggs || []).concat(orderAgg);
order[orderAggId] = dir;
order[orderAggPath] = dir;
},
},
{
Expand Down
6 changes: 6 additions & 0 deletions src/plugins/data/common/search/aggs/metrics/median.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,12 @@ describe('AggTypeMetricMedianProvider class', () => {
expect(dsl.median.percentiles.percents).toEqual([50]);
});

it('points to right value within multi metric for value bucket path', () => {
expect(aggConfigs.byId(METRIC_TYPES.MEDIAN)!.getValueBucketPath()).toEqual(
`${METRIC_TYPES.MEDIAN}.50`
);
});

it('converts the response', () => {
const agg = aggConfigs.getResponseAggs()[0];

Expand Down
3 changes: 3 additions & 0 deletions src/plugins/data/common/search/aggs/metrics/median.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ export const getMedianMetricAgg = () => {
values: { field: aggConfig.getFieldDisplayName() },
});
},
getValueBucketPath(aggConfig) {
return `${aggConfig.id}.50`;
},
params: [
{
name: 'field',
Expand Down
1 change: 1 addition & 0 deletions src/plugins/data/public/public.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ export class AggConfig {
getTimeRange(): import("../../../public").TimeRange | undefined;
// (undocumented)
getValue(bucket: any): any;
getValueBucketPath(): string;
// (undocumented)
id: string;
// (undocumented)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ describe('OrderAggParamEditor component', () => {

mount(<OrderByParamEditor {...props} />);

expect(setValue).toHaveBeenCalledWith('agg5');
expect(setValue).toHaveBeenCalledWith('agg3');
});

it('defaults to the _key metric if no agg is compatible', () => {
Expand Down

0 comments on commit fe53f2b

Please sign in to comment.