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] Implement rare terms #121500

Merged
merged 15 commits into from
Jan 18, 2022
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ readonly links: {
readonly significant_terms: string;
readonly terms: string;
readonly terms_doc_count_error: string;
readonly rare_terms: string;
readonly avg: string;
readonly avg_bucket: string;
readonly max_bucket: string;
Expand Down

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions src/core/public/doc_links/doc_links_service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ export class DocLinksService {
significant_terms: `${ELASTICSEARCH_DOCS}search-aggregations-bucket-significantterms-aggregation.html`,
terms: `${ELASTICSEARCH_DOCS}search-aggregations-bucket-terms-aggregation.html`,
terms_doc_count_error: `${ELASTICSEARCH_DOCS}search-aggregations-bucket-terms-aggregation.html#_per_bucket_document_count_error`,
rare_terms: `${ELASTICSEARCH_DOCS}search-aggregations-bucket-rare-terms-aggregation.html`,
avg: `${ELASTICSEARCH_DOCS}search-aggregations-metrics-avg-aggregation.html`,
avg_bucket: `${ELASTICSEARCH_DOCS}search-aggregations-pipeline-avg-bucket-aggregation.html`,
max_bucket: `${ELASTICSEARCH_DOCS}search-aggregations-pipeline-max-bucket-aggregation.html`,
Expand Down Expand Up @@ -746,6 +747,7 @@ export interface DocLinksStart {
readonly significant_terms: string;
readonly terms: string;
readonly terms_doc_count_error: string;
readonly rare_terms: string;
readonly avg: string;
readonly avg_bucket: string;
readonly max_bucket: string;
Expand Down
1 change: 1 addition & 0 deletions src/core/public/public.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -630,6 +630,7 @@ export interface DocLinksStart {
readonly significant_terms: string;
readonly terms: string;
readonly terms_doc_count_error: string;
readonly rare_terms: string;
readonly avg: string;
readonly avg_bucket: string;
readonly max_bucket: string;
Expand Down
2 changes: 2 additions & 0 deletions src/plugins/data/common/search/aggs/agg_types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ export const getAggTypes = () => ({
{ name: BUCKET_TYPES.IP_RANGE, fn: buckets.getIpRangeBucketAgg },
{ name: BUCKET_TYPES.TERMS, fn: buckets.getTermsBucketAgg },
{ name: BUCKET_TYPES.MULTI_TERMS, fn: buckets.getMultiTermsBucketAgg },
{ name: BUCKET_TYPES.RARE_TERMS, fn: buckets.getRareTermsBucketAgg },
{ name: BUCKET_TYPES.FILTER, fn: buckets.getFilterBucketAgg },
{ name: BUCKET_TYPES.FILTERS, fn: buckets.getFiltersBucketAgg },
{ name: BUCKET_TYPES.SIGNIFICANT_TERMS, fn: buckets.getSignificantTermsBucketAgg },
Expand All @@ -82,6 +83,7 @@ export const getAggTypesFunctions = () => [
buckets.aggDateHistogram,
buckets.aggTerms,
buckets.aggMultiTerms,
buckets.aggRareTerms,
buckets.aggSampler,
buckets.aggDiversifiedSampler,
metrics.aggAvg,
Expand Down
2 changes: 2 additions & 0 deletions src/plugins/data/common/search/aggs/aggs_service.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ describe('Aggs service', () => {
"ip_range",
"terms",
"multi_terms",
"rare_terms",
"filter",
"filters",
"significant_terms",
Expand Down Expand Up @@ -120,6 +121,7 @@ describe('Aggs service', () => {
"ip_range",
"terms",
"multi_terms",
"rare_terms",
"filter",
"filters",
"significant_terms",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export enum BUCKET_TYPES {
RANGE = 'range',
TERMS = 'terms',
MULTI_TERMS = 'multi_terms',
RARE_TERMS = 'rare_terms',
SIGNIFICANT_TERMS = 'significant_terms',
SIGNIFICANT_TEXT = 'significant_text',
GEOHASH_GRID = 'geohash_grid',
Expand Down
2 changes: 2 additions & 0 deletions src/plugins/data/common/search/aggs/buckets/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ export * from './terms_fn';
export * from './terms';
export * from './multi_terms_fn';
export * from './multi_terms';
export * from './rare_terms_fn';
export * from './rare_terms';
export * from './sampler_fn';
export * from './sampler';
export * from './diversified_sampler_fn';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ describe('Multi Terms Agg', () => {
5,
],
},
"function": "aggTerms",
"function": "aggMultiTerms",
"type": "function",
},
],
Expand Down
4 changes: 2 additions & 2 deletions src/plugins/data/common/search/aggs/buckets/multi_terms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { i18n } from '@kbn/i18n';
import { BucketAggType } from './bucket_agg_type';
import { BUCKET_TYPES } from './bucket_agg_types';
import { createFilterMultiTerms } from './create_filter/multi_terms';
import { aggTermsFnName } from './terms_fn';
import { aggMultiTermsFnName } from './multi_terms_fn';
import { AggConfigSerialized, BaseAggParams } from '../types';

import { MultiFieldKey } from './multi_field_key';
Expand Down Expand Up @@ -41,7 +41,7 @@ export const getMultiTermsBucketAgg = () => {
const keyCaches = new WeakMap();
return new BucketAggType({
name: BUCKET_TYPES.MULTI_TERMS,
expressionName: aggTermsFnName,
expressionName: aggMultiTermsFnName,
title: termsTitle,
makeLabel(agg) {
const params = agg.params;
Expand Down
103 changes: 103 additions & 0 deletions src/plugins/data/common/search/aggs/buckets/rare_terms.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

import { AggConfigs } from '../agg_configs';
import { mockAggTypesRegistry } from '../test_helpers';
import { BUCKET_TYPES } from './bucket_agg_types';
import type { IndexPatternField } from '../../..';
import { IndexPattern } from '../../..';

describe('rare terms Agg', () => {
const getAggConfigs = (params: Record<string, any> = {}) => {
const indexPattern = {
id: '1234',
title: 'logstash-*',
fields: [
{
name: 'field',
type: 'string',
esTypes: ['string'],
aggregatable: true,
filterable: true,
searchable: true,
},
{
name: 'string_field',
type: 'string',
esTypes: ['string'],
aggregatable: true,
filterable: true,
searchable: true,
},
{
name: 'empty_number_field',
type: 'number',
esTypes: ['number'],
aggregatable: true,
filterable: true,
searchable: true,
},
{
name: 'number_field',
type: 'number',
esTypes: ['number'],
aggregatable: true,
filterable: true,
searchable: true,
},
],
} as IndexPattern;

indexPattern.fields.getByName = (name) => ({ name } as unknown as IndexPatternField);
indexPattern.fields.filter = () => indexPattern.fields;

return new AggConfigs(
indexPattern,
[
{
id: 'test',
params,
type: BUCKET_TYPES.RARE_TERMS,
},
],
{ typesRegistry: mockAggTypesRegistry() }
);
};

test('produces the expected expression ast', () => {
const aggConfigs = getAggConfigs({
field: 'field',
max_doc_count: 5,
});
expect(aggConfigs.aggs[0].toExpressionAst()).toMatchInlineSnapshot(`
Object {
"chain": Array [
Object {
"arguments": Object {
"enabled": Array [
true,
],
"field": Array [
"field",
],
"id": Array [
"test",
],
"max_doc_count": Array [
5,
],
},
"function": "aggRareTerms",
"type": "function",
},
],
"type": "expression",
}
`);
});
});
60 changes: 60 additions & 0 deletions src/plugins/data/common/search/aggs/buckets/rare_terms.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

import { i18n } from '@kbn/i18n';

import { BucketAggType } from './bucket_agg_type';
import { BUCKET_TYPES } from './bucket_agg_types';
import { createFilterTerms } from './create_filter/terms';
import { aggRareTermsFnName } from './rare_terms_fn';
import { BaseAggParams } from '../types';

import { KBN_FIELD_TYPES } from '../../../../common';

const termsTitle = i18n.translate('data.search.aggs.buckets.rareTermsTitle', {
defaultMessage: 'Rare terms',
});

export interface AggParamsRareTerms extends BaseAggParams {
field: string;
max_doc_count?: number;
}

export const getRareTermsBucketAgg = () => {
return new BucketAggType({
name: BUCKET_TYPES.RARE_TERMS,
expressionName: aggRareTermsFnName,
title: termsTitle,
makeLabel(agg) {
return i18n.translate('data.search.aggs.rareTerms.aggTypesLabel', {
defaultMessage: 'Rare terms of {fieldName}',
values: {
fieldName: agg.getFieldDisplayName(),
},
});
},
createFilter: createFilterTerms,
params: [
{
name: 'field',
type: 'field',
filterFieldTypes: [
KBN_FIELD_TYPES.NUMBER,
KBN_FIELD_TYPES.BOOLEAN,
KBN_FIELD_TYPES.DATE,
KBN_FIELD_TYPES.IP,
KBN_FIELD_TYPES.STRING,
],
},
{
name: 'max_doc_count',
default: 1,
},
],
});
};
88 changes: 88 additions & 0 deletions src/plugins/data/common/search/aggs/buckets/rare_terms_fn.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

import { i18n } from '@kbn/i18n';
import { ExpressionFunctionDefinition } from 'src/plugins/expressions/common';
import { AggExpressionType, AggExpressionFunctionArgs, BUCKET_TYPES } from '../';

export const aggRareTermsFnName = 'aggRareTerms';

type Input = any;
type AggArgs = AggExpressionFunctionArgs<typeof BUCKET_TYPES.RARE_TERMS>;

type Output = AggExpressionType;
type FunctionDefinition = ExpressionFunctionDefinition<
typeof aggRareTermsFnName,
Input,
AggArgs,
Output
>;

export const aggRareTerms = (): FunctionDefinition => ({
name: aggRareTermsFnName,
help: i18n.translate('data.search.aggs.function.buckets.rareTerms.help', {
defaultMessage: 'Generates a serialized agg config for a Rare-Terms agg',
}),
type: 'agg_type',
args: {
id: {
types: ['string'],
help: i18n.translate('data.search.aggs.buckets.rareTerms.id.help', {
defaultMessage: 'ID for this aggregation',
}),
},
enabled: {
types: ['boolean'],
default: true,
help: i18n.translate('data.search.aggs.buckets.rareTerms.enabled.help', {
defaultMessage: 'Specifies whether this aggregation should be enabled',
}),
},
schema: {
types: ['string'],
help: i18n.translate('data.search.aggs.buckets.rareTerms.schema.help', {
defaultMessage: 'Schema to use for this aggregation',
}),
},
field: {
types: ['string'],
required: true,
help: i18n.translate('data.search.aggs.buckets.rareTerms.fields.help', {
defaultMessage: 'Field to use for this aggregation',
}),
},
max_doc_count: {
types: ['number'],
help: i18n.translate('data.search.aggs.buckets.rareTerms.maxDocCount.help', {
defaultMessage: 'Maximum number of times a term is allowed to occur to qualify as rare',
}),
},
json: {
types: ['string'],
help: i18n.translate('data.search.aggs.buckets.multiTerms.json.help', {
defaultMessage: 'Advanced json to include when the agg is sent to Elasticsearch',
}),
},
},
fn: (input, args) => {
const { id, enabled, schema, ...rest } = args;

return {
type: 'agg_type',
value: {
id,
enabled,
schema,
type: BUCKET_TYPES.RARE_TERMS,
params: {
...rest,
},
},
};
},
});
4 changes: 4 additions & 0 deletions src/plugins/data/common/search/aggs/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ import {
AggParamsSum,
AggParamsTerms,
AggParamsMultiTerms,
AggParamsRareTerms,
AggParamsTopHit,
aggPercentileRanks,
aggPercentiles,
Expand All @@ -78,6 +79,7 @@ import {
aggSum,
aggTerms,
aggMultiTerms,
aggRareTerms,
aggTopHit,
AggTypesRegistry,
AggTypesRegistrySetup,
Expand Down Expand Up @@ -166,6 +168,7 @@ export interface AggParamsMapping {
[BUCKET_TYPES.DATE_HISTOGRAM]: AggParamsDateHistogram;
[BUCKET_TYPES.TERMS]: AggParamsTerms;
[BUCKET_TYPES.MULTI_TERMS]: AggParamsMultiTerms;
[BUCKET_TYPES.RARE_TERMS]: AggParamsRareTerms;
[BUCKET_TYPES.SAMPLER]: AggParamsSampler;
[BUCKET_TYPES.DIVERSIFIED_SAMPLER]: AggParamsDiversifiedSampler;
[METRIC_TYPES.AVG]: AggParamsAvg;
Expand Down Expand Up @@ -209,6 +212,7 @@ export interface AggFunctionsMapping {
aggDateHistogram: ReturnType<typeof aggDateHistogram>;
aggTerms: ReturnType<typeof aggTerms>;
aggMultiTerms: ReturnType<typeof aggMultiTerms>;
aggRareTerms: ReturnType<typeof aggRareTerms>;
aggAvg: ReturnType<typeof aggAvg>;
aggBucketAvg: ReturnType<typeof aggBucketAvg>;
aggBucketMax: ReturnType<typeof aggBucketMax>;
Expand Down
Loading