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

[Lens] Create a filter with field:value when last value metric is used on a datatable #160509

Merged
merged 4 commits into from
Jun 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,36 @@
*/

import { AggConfigs, IAggConfigs } from '../agg_configs';
import { mockAggTypesRegistry } from '../test_helpers';
import { AggTypesDependencies } from '../agg_types';
import { mockAggTypesDependencies, mockAggTypesRegistry } from '../test_helpers';
import { getFilteredMetricAgg } from './filtered_metric';
import { IMetricAggConfig } from './metric_agg_type';
import { METRIC_TYPES } from './metric_agg_types';

describe('filtered metric agg type', () => {
let aggConfigs: IAggConfigs;
let aggTypesDependencies: AggTypesDependencies;
const typesRegistry = mockAggTypesRegistry();
const field = {
name: 'bytes',
filterable: true,
};
const indexPattern = {
id: '1234',
title: 'logstash-*',
fields: {
getByName: () => field,
filter: () => [field],
find: () => field,
},
} as any;

beforeEach(() => {
const typesRegistry = mockAggTypesRegistry();
const field = {
name: 'bytes',
jest.resetAllMocks();
aggTypesDependencies = {
...mockAggTypesDependencies,
getConfig: jest.fn(),
};
const indexPattern = {
id: '1234',
title: 'logstash-*',
fields: {
getByName: () => field,
filter: () => [field],
},
} as any;

aggConfigs = new AggConfigs(
indexPattern,
Expand Down Expand Up @@ -76,4 +87,53 @@ describe('filtered metric agg type', () => {

expect(agg.getResponseId()).toEqual('filtered_metric-bucket');
});
it.each`
aggType
${'top_metrics'}
${'top_hits'}
`('returns phrase filter for filtered metric for $aggType', ({ aggType }) => {
const topMetricsAggConfigs = new AggConfigs(
indexPattern,
[
{
id: METRIC_TYPES.FILTERED_METRIC,
type: METRIC_TYPES.FILTERED_METRIC,
schema: 'metric',
params: {
customBucket: {
type: 'filter',
params: {
filter: { language: 'kuery', query: 'a: b' },
},
},
customMetric: {
type: aggType,
params: {
field: 'bytes',
},
},
},
},
],
{
typesRegistry,
},
jest.fn()
);

expect(
getFilteredMetricAgg(aggTypesDependencies).createFilter!(
topMetricsAggConfigs.aggs[0] as IMetricAggConfig,
10
).query.match_phrase
).toEqual({ bytes: 10 });
});
it('returns filter from the custom bucket filter parameter for metric', () => {
expect(
getFilteredMetricAgg(aggTypesDependencies).createFilter!(
aggConfigs.aggs[0] as IMetricAggConfig,
'10'
).query.bool.filter[0].bool.should[0].match
).toEqual({ bytes: 'b' });
});
});
16 changes: 9 additions & 7 deletions src/plugins/data/common/search/aggs/metrics/filtered_metric.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,16 +51,18 @@ export const getFilteredMetricAgg = ({ getConfig }: FiltersMetricAggDependencies
hasNoDslParams: true,
getSerializedFormat,
createFilter: (agg, inputState) => {
const indexPattern = agg.getIndexPattern();
if (
agg.params.customMetric.type.name === 'top_hits' ||
agg.params.customMetric.type.name === 'top_metrics'
) {
return agg.params.customMetric.createFilter(inputState);
}
if (!agg.params.customBucket.params.filter) return;
const esQueryConfigs = getEsQueryConfig({ get: getConfig });
return buildQueryFilter(
buildEsQuery(
agg.getIndexPattern(),
[agg.params.customBucket.params.filter],
[],
esQueryConfigs
),
agg.getIndexPattern().id!,
buildEsQuery(indexPattern, [agg.params.customBucket.params.filter], [], esQueryConfigs),
indexPattern.id!,
agg.params.customBucket.params.filter.query
);
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,12 @@
* Side Public License, v 1.
*/

import { buildExistsFilter } from '@kbn/es-query';
import {
BooleanRelation,
buildCombinedFilter,
buildExistsFilter,
buildPhraseFilter,
} from '@kbn/es-query';
import { AggConfig } from '../../agg_config';
import { IMetricAggConfig } from '../metric_agg_type';

Expand All @@ -19,3 +24,21 @@ export const createMetricFilter = <TMetricAggConfig extends AggConfig = IMetricA
return buildExistsFilter(aggConfig.getField(), indexPattern);
}
};

export const createTopHitFilter = <TMetricAggConfig extends AggConfig = IMetricAggConfig>(
aggConfig: TMetricAggConfig,
key: string
) => {
const indexPattern = aggConfig.getIndexPattern();
const field = aggConfig.getField();
if (!field) {
return;
}
return Array.isArray(key)
? buildCombinedFilter(
BooleanRelation.OR,
key.map((k) => buildPhraseFilter(field, k, indexPattern)),
indexPattern
)
: buildPhraseFilter(field, key, indexPattern);
};
5 changes: 5 additions & 0 deletions src/plugins/data/common/search/aggs/metrics/top_hit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -402,5 +402,10 @@ describe('Top hit metric', () => {
});
});
});
it('returns phrase filter', () => {
expect(getTopHitMetricAgg().createFilter!(aggConfig, '10').query.match_phrase).toEqual({
bytes: 10,
});
});
});
});
2 changes: 2 additions & 0 deletions src/plugins/data/common/search/aggs/metrics/top_hit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { IMetricAggConfig, MetricAggType } from './metric_agg_type';
import { METRIC_TYPES } from './metric_agg_types';
import { flattenHit, KBN_FIELD_TYPES } from '../../..';
import { BaseAggParams } from '../types';
import { createTopHitFilter } from './lib/create_filter';

export interface BaseAggParamsTopHit extends BaseAggParams {
field: string;
Expand Down Expand Up @@ -256,5 +257,6 @@ export const getTopHitMetricAgg = () => {
}
return values;
},
createFilter: createTopHitFilter,
});
};
11 changes: 11 additions & 0 deletions src/plugins/data/common/search/aggs/metrics/top_metrics.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { AggConfigs } from '../agg_configs';
import { mockAggTypesRegistry } from '../test_helpers';
import { IMetricAggConfig } from './metric_agg_type';
import { KBN_FIELD_TYPES } from '../../..';
import { CombinedFilter } from '@kbn/es-query';

describe('Top metrics metric', () => {
let aggConfig: IMetricAggConfig;
Expand Down Expand Up @@ -191,5 +192,15 @@ describe('Top metrics metric', () => {
init({ fieldName: 'bytes' });
expect(getTopMetricsMetricAgg().getValue(aggConfig, bucket)).toEqual([1024, 512, 256]);
});
it('returns phrase filter', () => {
expect(getTopMetricsMetricAgg().createFilter!(aggConfig, '10').query.match_phrase).toEqual({
bytes: 10,
});
});
it('returns combined OR filter for array values', () => {
const params = getTopMetricsMetricAgg().createFilter!(aggConfig, ['10', '20']).meta
.params as CombinedFilter['meta']['params'];
expect(params.map((p) => p.query!.match_phrase)).toEqual([{ bytes: 10 }, { bytes: 20 }]);
});
});
});
2 changes: 2 additions & 0 deletions src/plugins/data/common/search/aggs/metrics/top_metrics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { IMetricAggConfig, MetricAggType } from './metric_agg_type';
import { METRIC_TYPES } from './metric_agg_types';
import { DataViewField, KBN_FIELD_TYPES } from '../../..';
import { BaseAggParams } from '../types';
import { createTopHitFilter } from './lib/create_filter';

export interface BaseAggParamsTopMetrics extends BaseAggParams {
field: string;
Expand Down Expand Up @@ -162,5 +163,6 @@ export const getTopMetricsMetricAgg = () => {
if (results.length === 1) return results[0];
return results;
},
createFilter: createTopHitFilter,
});
};