mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
Add Significant Text agg to AggConfigs (#122166)
This commit is contained in:
parent
72297e5cdd
commit
673c88f7b9
27 changed files with 551 additions and 6 deletions
|
@ -59,6 +59,7 @@ export const getAggTypes = () => ({
|
|||
{ name: BUCKET_TYPES.FILTER, fn: buckets.getFilterBucketAgg },
|
||||
{ name: BUCKET_TYPES.FILTERS, fn: buckets.getFiltersBucketAgg },
|
||||
{ name: BUCKET_TYPES.SIGNIFICANT_TERMS, fn: buckets.getSignificantTermsBucketAgg },
|
||||
{ name: BUCKET_TYPES.SIGNIFICANT_TEXT, fn: buckets.getSignificantTextBucketAgg },
|
||||
{ name: BUCKET_TYPES.GEOHASH_GRID, fn: buckets.getGeoHashBucketAgg },
|
||||
{ name: BUCKET_TYPES.GEOTILE_GRID, fn: buckets.getGeoTitleBucketAgg },
|
||||
{ name: BUCKET_TYPES.SAMPLER, fn: buckets.getSamplerBucketAgg },
|
||||
|
@ -71,6 +72,7 @@ export const getAggTypesFunctions = () => [
|
|||
buckets.aggFilter,
|
||||
buckets.aggFilters,
|
||||
buckets.aggSignificantTerms,
|
||||
buckets.aggSignificantText,
|
||||
buckets.aggIpRange,
|
||||
buckets.aggDateRange,
|
||||
buckets.aggRange,
|
||||
|
|
|
@ -71,6 +71,7 @@ describe('Aggs service', () => {
|
|||
"filter",
|
||||
"filters",
|
||||
"significant_terms",
|
||||
"significant_text",
|
||||
"geohash_grid",
|
||||
"geotile_grid",
|
||||
"sampler",
|
||||
|
@ -122,6 +123,7 @@ describe('Aggs service', () => {
|
|||
"filter",
|
||||
"filters",
|
||||
"significant_terms",
|
||||
"significant_text",
|
||||
"geohash_grid",
|
||||
"geotile_grid",
|
||||
"sampler",
|
||||
|
|
|
@ -8,9 +8,10 @@
|
|||
|
||||
import moment from 'moment';
|
||||
import { IAggConfig } from '../agg_config';
|
||||
import { GenericBucket, IAggConfigs, KBN_FIELD_TYPES } from '../../../../common';
|
||||
import { FilterFieldFn, GenericBucket, IAggConfigs } from '../../../../common';
|
||||
import { AggType, AggTypeConfig } from '../agg_type';
|
||||
import { AggParamType } from '../param_types/agg';
|
||||
import type { FieldTypes } from '../param_types/field';
|
||||
|
||||
export interface IBucketAggConfig extends IAggConfig {
|
||||
type: InstanceType<typeof BucketAggType>;
|
||||
|
@ -19,7 +20,14 @@ export interface IBucketAggConfig extends IAggConfig {
|
|||
export interface BucketAggParam<TBucketAggConfig extends IAggConfig>
|
||||
extends AggParamType<TBucketAggConfig> {
|
||||
scriptable?: boolean;
|
||||
filterFieldTypes?: KBN_FIELD_TYPES | KBN_FIELD_TYPES[] | '*';
|
||||
filterFieldTypes?: FieldTypes;
|
||||
onlyAggregatable?: boolean;
|
||||
|
||||
/**
|
||||
* Filter available fields by passing filter fn on a {@link DataViewField}
|
||||
* If used, takes precedence over filterFieldTypes and other filter params
|
||||
*/
|
||||
filterField?: FilterFieldFn;
|
||||
}
|
||||
|
||||
const bucketType = 'buckets';
|
||||
|
|
|
@ -16,6 +16,7 @@ export enum BUCKET_TYPES {
|
|||
TERMS = 'terms',
|
||||
MULTI_TERMS = 'multi_terms',
|
||||
SIGNIFICANT_TERMS = 'significant_terms',
|
||||
SIGNIFICANT_TEXT = 'significant_text',
|
||||
GEOHASH_GRID = 'geohash_grid',
|
||||
GEOTILE_GRID = 'geotile_grid',
|
||||
DATE_HISTOGRAM = 'date_histogram',
|
||||
|
|
|
@ -34,6 +34,8 @@ export * from './range_fn';
|
|||
export * from './range';
|
||||
export * from './significant_terms_fn';
|
||||
export * from './significant_terms';
|
||||
export * from './significant_text_fn';
|
||||
export * from './significant_text';
|
||||
export * from './terms_fn';
|
||||
export * from './terms';
|
||||
export * from './multi_terms_fn';
|
||||
|
|
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* 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';
|
||||
|
||||
describe('Significant Text Agg', () => {
|
||||
const getAggConfigs = (params: Record<string, any> = {}) => {
|
||||
const indexPattern = {
|
||||
id: '1234',
|
||||
title: 'logstash-*',
|
||||
fields: {
|
||||
getByName: () => field,
|
||||
filter: () => [field],
|
||||
},
|
||||
} as any;
|
||||
|
||||
const field = {
|
||||
name: 'field',
|
||||
indexPattern,
|
||||
};
|
||||
|
||||
return new AggConfigs(
|
||||
indexPattern,
|
||||
[
|
||||
{
|
||||
id: 'test',
|
||||
type: BUCKET_TYPES.SIGNIFICANT_TEXT,
|
||||
params,
|
||||
},
|
||||
],
|
||||
{
|
||||
typesRegistry: mockAggTypesRegistry(),
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
test('produces the expected expression ast', () => {
|
||||
const aggConfigs = getAggConfigs({
|
||||
size: 'SIZE',
|
||||
field: {
|
||||
name: 'FIELD',
|
||||
},
|
||||
});
|
||||
expect(aggConfigs.aggs[0].toExpressionAst()).toMatchInlineSnapshot(`
|
||||
Object {
|
||||
"chain": Array [
|
||||
Object {
|
||||
"arguments": Object {
|
||||
"enabled": Array [
|
||||
true,
|
||||
],
|
||||
"field": Array [
|
||||
"FIELD",
|
||||
],
|
||||
"id": Array [
|
||||
"test",
|
||||
],
|
||||
"size": Array [
|
||||
"SIZE",
|
||||
],
|
||||
},
|
||||
"function": "aggSignificantText",
|
||||
"type": "function",
|
||||
},
|
||||
],
|
||||
"type": "expression",
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
test('should generate correct label', () => {
|
||||
const aggConfigs = getAggConfigs({
|
||||
size: 'SIZE',
|
||||
field: {
|
||||
name: 'FIELD',
|
||||
},
|
||||
});
|
||||
const label = aggConfigs.aggs[0].makeLabel();
|
||||
|
||||
expect(label).toBe('Top SIZE unusual terms from "FIELD" text');
|
||||
});
|
||||
});
|
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
* 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 { migrateIncludeExcludeFormat } from './migrate_include_exclude_format';
|
||||
import { BUCKET_TYPES } from './bucket_agg_types';
|
||||
import { aggSignificantTextFnName } from './significant_text_fn';
|
||||
import { KBN_FIELD_TYPES, ES_FIELD_TYPES } from '../../../../common';
|
||||
import { BaseAggParams } from '../types';
|
||||
import { createFilterTerms } from './create_filter/terms';
|
||||
|
||||
const significantTextTitle = i18n.translate('data.search.aggs.buckets.significantTextTitle', {
|
||||
defaultMessage: 'Significant Text',
|
||||
});
|
||||
|
||||
export interface AggParamsSignificantText extends BaseAggParams {
|
||||
field: string;
|
||||
size?: number;
|
||||
min_doc_count?: number;
|
||||
filter_duplicate_text?: boolean;
|
||||
exclude?: string;
|
||||
include?: string;
|
||||
}
|
||||
|
||||
export const getSignificantTextBucketAgg = () =>
|
||||
new BucketAggType({
|
||||
name: BUCKET_TYPES.SIGNIFICANT_TEXT,
|
||||
expressionName: aggSignificantTextFnName,
|
||||
title: significantTextTitle,
|
||||
makeLabel(aggConfig) {
|
||||
return i18n.translate('data.search.aggs.buckets.significantTextLabel', {
|
||||
defaultMessage: 'Top {size} unusual terms from "{fieldName}" text',
|
||||
values: {
|
||||
size: aggConfig.params.size,
|
||||
fieldName: aggConfig.getFieldDisplayName(),
|
||||
},
|
||||
});
|
||||
},
|
||||
createFilter: createFilterTerms,
|
||||
params: [
|
||||
{
|
||||
name: 'field',
|
||||
type: 'field',
|
||||
/**
|
||||
* Significant text is available only for ES_FIELD_TYPES.TEXT,
|
||||
* This information is not available from field.type, so we have to check this using underlying esTypes
|
||||
*/
|
||||
filterField: (field) =>
|
||||
Boolean(
|
||||
field.type === KBN_FIELD_TYPES.STRING && field.esTypes?.includes(ES_FIELD_TYPES.TEXT)
|
||||
),
|
||||
},
|
||||
{
|
||||
name: 'size',
|
||||
type: 'number',
|
||||
},
|
||||
{
|
||||
name: 'min_doc_count',
|
||||
type: 'number',
|
||||
},
|
||||
{
|
||||
name: 'filter_duplicate_text',
|
||||
type: 'boolean',
|
||||
},
|
||||
{
|
||||
name: 'exclude',
|
||||
displayName: i18n.translate('data.search.aggs.buckets.significantText.excludeLabel', {
|
||||
defaultMessage: 'Exclude',
|
||||
}),
|
||||
type: 'string',
|
||||
advanced: true,
|
||||
...migrateIncludeExcludeFormat,
|
||||
},
|
||||
{
|
||||
name: 'include',
|
||||
displayName: i18n.translate('data.search.aggs.buckets.significantText.includeLabel', {
|
||||
defaultMessage: 'Include',
|
||||
}),
|
||||
type: 'string',
|
||||
advanced: true,
|
||||
...migrateIncludeExcludeFormat,
|
||||
},
|
||||
],
|
||||
});
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* 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 { functionWrapper } from '../test_helpers';
|
||||
import { aggSignificantText } from './significant_text_fn';
|
||||
|
||||
describe('agg_expression_functions', () => {
|
||||
describe('aggSignificantText', () => {
|
||||
const fn = functionWrapper(aggSignificantText());
|
||||
|
||||
test('fills in defaults when only required args are provided', () => {
|
||||
const actual = fn({
|
||||
field: 'machine.os',
|
||||
});
|
||||
expect(actual).toMatchInlineSnapshot(`
|
||||
Object {
|
||||
"type": "agg_type",
|
||||
"value": Object {
|
||||
"enabled": true,
|
||||
"id": undefined,
|
||||
"params": Object {
|
||||
"customLabel": undefined,
|
||||
"exclude": undefined,
|
||||
"field": "machine.os",
|
||||
"filter_duplicate_text": undefined,
|
||||
"include": undefined,
|
||||
"json": undefined,
|
||||
"min_doc_count": undefined,
|
||||
"size": undefined,
|
||||
},
|
||||
"schema": undefined,
|
||||
"type": "significant_text",
|
||||
},
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
test('includes optional params when they are provided', () => {
|
||||
const actual = fn({
|
||||
id: '1',
|
||||
enabled: false,
|
||||
schema: 'whatever',
|
||||
field: 'machine.os',
|
||||
size: 6,
|
||||
include: 'win',
|
||||
exclude: 'ios',
|
||||
filter_duplicate_text: true,
|
||||
min_doc_count: 10,
|
||||
});
|
||||
|
||||
expect(actual.value).toMatchInlineSnapshot(`
|
||||
Object {
|
||||
"enabled": false,
|
||||
"id": "1",
|
||||
"params": Object {
|
||||
"customLabel": undefined,
|
||||
"exclude": "ios",
|
||||
"field": "machine.os",
|
||||
"filter_duplicate_text": true,
|
||||
"include": "win",
|
||||
"json": undefined,
|
||||
"min_doc_count": 10,
|
||||
"size": 6,
|
||||
},
|
||||
"schema": "whatever",
|
||||
"type": "significant_text",
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
test('correctly parses json string argument', () => {
|
||||
const actual = fn({
|
||||
field: 'machine.os',
|
||||
json: '{ "foo": true }',
|
||||
});
|
||||
|
||||
expect(actual.value.params.json).toEqual('{ "foo": true }');
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,120 @@
|
|||
/*
|
||||
* 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 aggSignificantTextFnName = 'aggSignificantText';
|
||||
|
||||
type Input = any;
|
||||
type AggArgs = AggExpressionFunctionArgs<typeof BUCKET_TYPES.SIGNIFICANT_TEXT>;
|
||||
|
||||
type Arguments = AggArgs;
|
||||
|
||||
type Output = AggExpressionType;
|
||||
type FunctionDefinition = ExpressionFunctionDefinition<
|
||||
typeof aggSignificantTextFnName,
|
||||
Input,
|
||||
Arguments,
|
||||
Output
|
||||
>;
|
||||
|
||||
export const aggSignificantText = (): FunctionDefinition => ({
|
||||
name: aggSignificantTextFnName,
|
||||
help: i18n.translate('data.search.aggs.function.buckets.significantText.help', {
|
||||
defaultMessage: 'Generates a serialized agg config for a Significant Text agg',
|
||||
}),
|
||||
type: 'agg_type',
|
||||
args: {
|
||||
id: {
|
||||
types: ['string'],
|
||||
help: i18n.translate('data.search.aggs.buckets.significantText.id.help', {
|
||||
defaultMessage: 'ID for this aggregation',
|
||||
}),
|
||||
},
|
||||
enabled: {
|
||||
types: ['boolean'],
|
||||
default: true,
|
||||
help: i18n.translate('data.search.aggs.buckets.significantText.enabled.help', {
|
||||
defaultMessage: 'Specifies whether this aggregation should be enabled',
|
||||
}),
|
||||
},
|
||||
schema: {
|
||||
types: ['string'],
|
||||
help: i18n.translate('data.search.aggs.buckets.significantText.schema.help', {
|
||||
defaultMessage: 'Schema to use for this aggregation',
|
||||
}),
|
||||
},
|
||||
field: {
|
||||
types: ['string'],
|
||||
required: true,
|
||||
help: i18n.translate('data.search.aggs.buckets.significantText.field.help', {
|
||||
defaultMessage: 'Field to use for this aggregation',
|
||||
}),
|
||||
},
|
||||
size: {
|
||||
types: ['number'],
|
||||
help: i18n.translate('data.search.aggs.buckets.significantText.size.help', {
|
||||
defaultMessage: 'Max number of buckets to retrieve',
|
||||
}),
|
||||
},
|
||||
min_doc_count: {
|
||||
types: ['number'],
|
||||
help: i18n.translate('data.search.aggs.buckets.significantText.minDocCount.help', {
|
||||
defaultMessage: 'Return terms that match more than a configured number',
|
||||
}),
|
||||
},
|
||||
filter_duplicate_text: {
|
||||
types: ['boolean'],
|
||||
help: i18n.translate('data.search.aggs.buckets.significantText.filterDuplicateText.help', {
|
||||
defaultMessage: 'Filtering near-duplicate text',
|
||||
}),
|
||||
},
|
||||
exclude: {
|
||||
types: ['string'],
|
||||
help: i18n.translate('data.search.aggs.buckets.significantText.exclude.help', {
|
||||
defaultMessage: 'Specific bucket values to exclude from results',
|
||||
}),
|
||||
},
|
||||
include: {
|
||||
types: ['string'],
|
||||
help: i18n.translate('data.search.aggs.buckets.significantText.include.help', {
|
||||
defaultMessage: 'Specific bucket values to include in results',
|
||||
}),
|
||||
},
|
||||
json: {
|
||||
types: ['string'],
|
||||
help: i18n.translate('data.search.aggs.buckets.significantText.json.help', {
|
||||
defaultMessage: 'Advanced json to include when the agg is sent to Elasticsearch',
|
||||
}),
|
||||
},
|
||||
customLabel: {
|
||||
types: ['string'],
|
||||
help: i18n.translate('data.search.aggs.buckets.significantText.customLabel.help', {
|
||||
defaultMessage: 'Represents a custom label for this aggregation',
|
||||
}),
|
||||
},
|
||||
},
|
||||
fn: (input, args) => {
|
||||
const { id, enabled, schema, ...rest } = args;
|
||||
|
||||
return {
|
||||
type: 'agg_type',
|
||||
value: {
|
||||
id,
|
||||
enabled,
|
||||
schema,
|
||||
type: BUCKET_TYPES.SIGNIFICANT_TEXT,
|
||||
params: {
|
||||
...rest,
|
||||
},
|
||||
},
|
||||
};
|
||||
},
|
||||
});
|
|
@ -91,5 +91,47 @@ describe('Field', () => {
|
|||
|
||||
expect(fields.length).toBe(2);
|
||||
});
|
||||
|
||||
it('should filter by KBN type', () => {
|
||||
const aggParam = new FieldParamType({
|
||||
name: 'field',
|
||||
type: 'field',
|
||||
filterFieldTypes: KBN_FIELD_TYPES.NUMBER,
|
||||
});
|
||||
|
||||
const fields = aggParam.getAvailableFields(agg);
|
||||
|
||||
expect(fields.length).toBe(1);
|
||||
expect(fields[0]).toBe(indexPattern.fields[0]);
|
||||
});
|
||||
|
||||
it('should filter by field filter predicate', () => {
|
||||
const aggParam = new FieldParamType({
|
||||
name: 'field',
|
||||
type: 'field',
|
||||
filterField: (field: typeof indexPattern['fields'][0]) =>
|
||||
field.esTypes?.includes(ES_FIELD_TYPES.TEXT),
|
||||
});
|
||||
|
||||
const fields = aggParam.getAvailableFields(agg);
|
||||
|
||||
expect(fields.length).toBe(1);
|
||||
expect(fields[0]).toBe(indexPattern.fields[1]);
|
||||
});
|
||||
|
||||
it('should filter by field filter predicate and ignore other filter settings', () => {
|
||||
const aggParam = new FieldParamType({
|
||||
name: 'field',
|
||||
type: 'field',
|
||||
filterField: (field: typeof indexPattern['fields'][0]) =>
|
||||
field.esTypes?.includes(ES_FIELD_TYPES.TEXT),
|
||||
filterFieldTypes: KBN_FIELD_TYPES.NUMBER,
|
||||
});
|
||||
|
||||
const fields = aggParam.getAvailableFields(agg);
|
||||
|
||||
expect(fields.length).toBe(1);
|
||||
expect(fields[0]).toBe(indexPattern.fields[1]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -15,11 +15,14 @@ import {
|
|||
import { BaseParamType } from './base';
|
||||
import { propFilter } from '../utils';
|
||||
import { KBN_FIELD_TYPES } from '../../../kbn_field_types/types';
|
||||
import { isNestedField, IndexPatternField } from '../../../../../data_views/common';
|
||||
import { isNestedField, IndexPatternField, DataViewField } from '../../../../../data_views/common';
|
||||
|
||||
const filterByType = propFilter('type');
|
||||
|
||||
export type FieldTypes = KBN_FIELD_TYPES | KBN_FIELD_TYPES[] | '*';
|
||||
|
||||
export type FilterFieldFn = (field: DataViewField) => boolean;
|
||||
|
||||
// TODO need to make a more explicit interface for this
|
||||
export type IFieldParamType = FieldParamType;
|
||||
|
||||
|
@ -29,11 +32,18 @@ export class FieldParamType extends BaseParamType {
|
|||
filterFieldTypes: FieldTypes;
|
||||
onlyAggregatable: boolean;
|
||||
|
||||
/**
|
||||
* Filter available fields by passing filter fn on a {@link DataViewField}
|
||||
* If used, takes precedence over filterFieldTypes and other filter params
|
||||
*/
|
||||
filterField?: FilterFieldFn;
|
||||
|
||||
constructor(config: Record<string, any>) {
|
||||
super(config);
|
||||
|
||||
this.filterFieldTypes = config.filterFieldTypes || '*';
|
||||
this.onlyAggregatable = config.onlyAggregatable !== false;
|
||||
this.filterField = config.filterField;
|
||||
|
||||
if (!config.write) {
|
||||
this.write = (aggConfig: IAggConfig, output: Record<string, any>) => {
|
||||
|
@ -126,7 +136,11 @@ export class FieldParamType extends BaseParamType {
|
|||
getAvailableFields = (aggConfig: IAggConfig) => {
|
||||
const fields = aggConfig.getIndexPattern().fields;
|
||||
const filteredFields = fields.filter((field: IndexPatternField) => {
|
||||
const { onlyAggregatable, scriptable, filterFieldTypes } = this;
|
||||
const { onlyAggregatable, scriptable, filterFieldTypes, filterField } = this;
|
||||
|
||||
if (filterField) {
|
||||
return filterField(field);
|
||||
}
|
||||
|
||||
if (
|
||||
(onlyAggregatable && (!field.aggregatable || isNestedField(field))) ||
|
||||
|
|
|
@ -92,6 +92,7 @@ import {
|
|||
} from './';
|
||||
import { AggParamsSampler } from './buckets/sampler';
|
||||
import { AggParamsDiversifiedSampler } from './buckets/diversified_sampler';
|
||||
import { AggParamsSignificantText } from './buckets/significant_text';
|
||||
|
||||
export type { IAggConfig, AggConfigSerialized } from './agg_config';
|
||||
export type { CreateAggConfigParams, IAggConfigs } from './agg_configs';
|
||||
|
@ -158,6 +159,7 @@ export interface AggParamsMapping {
|
|||
[BUCKET_TYPES.FILTER]: AggParamsFilter;
|
||||
[BUCKET_TYPES.FILTERS]: AggParamsFilters;
|
||||
[BUCKET_TYPES.SIGNIFICANT_TERMS]: AggParamsSignificantTerms;
|
||||
[BUCKET_TYPES.SIGNIFICANT_TEXT]: AggParamsSignificantText;
|
||||
[BUCKET_TYPES.GEOTILE_GRID]: AggParamsGeoTile;
|
||||
[BUCKET_TYPES.GEOHASH_GRID]: AggParamsGeoHash;
|
||||
[BUCKET_TYPES.HISTOGRAM]: AggParamsHistogram;
|
||||
|
|
|
@ -53,7 +53,7 @@ describe('AggsService - public', () => {
|
|||
test('registers default agg types', () => {
|
||||
service.setup(setupDeps);
|
||||
const start = service.start(startDeps);
|
||||
expect(start.types.getAll().buckets.length).toBe(14);
|
||||
expect(start.types.getAll().buckets.length).toBe(15);
|
||||
expect(start.types.getAll().metrics.length).toBe(23);
|
||||
});
|
||||
|
||||
|
@ -69,7 +69,7 @@ describe('AggsService - public', () => {
|
|||
);
|
||||
|
||||
const start = service.start(startDeps);
|
||||
expect(start.types.getAll().buckets.length).toBe(15);
|
||||
expect(start.types.getAll().buckets.length).toBe(16);
|
||||
expect(start.types.getAll().buckets.some(({ name }) => name === 'foo')).toBe(true);
|
||||
expect(start.types.getAll().metrics.length).toBe(24);
|
||||
expect(start.types.getAll().metrics.some(({ name }) => name === 'bar')).toBe(true);
|
||||
|
|
|
@ -105,6 +105,7 @@ export const getHeatmapVisTypeDefinition = ({
|
|||
'!sampler',
|
||||
'!diversified_sampler',
|
||||
'!multi_terms',
|
||||
'!significant_text',
|
||||
],
|
||||
},
|
||||
{
|
||||
|
@ -120,6 +121,7 @@ export const getHeatmapVisTypeDefinition = ({
|
|||
'!sampler',
|
||||
'!diversified_sampler',
|
||||
'!multi_terms',
|
||||
'!significant_text',
|
||||
],
|
||||
},
|
||||
{
|
||||
|
@ -142,6 +144,7 @@ export const getHeatmapVisTypeDefinition = ({
|
|||
'!sampler',
|
||||
'!diversified_sampler',
|
||||
'!multi_terms',
|
||||
'!significant_text',
|
||||
],
|
||||
},
|
||||
],
|
||||
|
|
|
@ -93,6 +93,7 @@ export const createMetricVisTypeDefinition = (): VisTypeDefinition<VisParams> =>
|
|||
'!sampler',
|
||||
'!diversified_sampler',
|
||||
'!multi_terms',
|
||||
'!significant_text',
|
||||
],
|
||||
},
|
||||
],
|
||||
|
|
|
@ -94,6 +94,7 @@ export const samplePieVis = {
|
|||
'!sampler',
|
||||
'!diversified_sampler',
|
||||
'!multi_terms',
|
||||
'!significant_text',
|
||||
],
|
||||
editor: false,
|
||||
params: [],
|
||||
|
@ -112,6 +113,7 @@ export const samplePieVis = {
|
|||
'!sampler',
|
||||
'!diversified_sampler',
|
||||
'!multi_terms',
|
||||
'!significant_text',
|
||||
],
|
||||
params: [
|
||||
{
|
||||
|
|
|
@ -94,6 +94,7 @@ export const getPieVisTypeDefinition = ({
|
|||
'!sampler',
|
||||
'!diversified_sampler',
|
||||
'!multi_terms',
|
||||
'!significant_text',
|
||||
],
|
||||
},
|
||||
{
|
||||
|
@ -112,6 +113,7 @@ export const getPieVisTypeDefinition = ({
|
|||
'!sampler',
|
||||
'!diversified_sampler',
|
||||
'!multi_terms',
|
||||
'!significant_text',
|
||||
],
|
||||
},
|
||||
],
|
||||
|
|
|
@ -139,6 +139,7 @@ export const gaugeVisTypeDefinition: VisTypeDefinition<GaugeVisParams> = {
|
|||
'!sampler',
|
||||
'!diversified_sampler',
|
||||
'!multi_terms',
|
||||
'!significant_text',
|
||||
],
|
||||
},
|
||||
],
|
||||
|
|
|
@ -103,6 +103,7 @@ export const goalVisTypeDefinition: VisTypeDefinition<GaugeVisParams> = {
|
|||
'!sampler',
|
||||
'!diversified_sampler',
|
||||
'!multi_terms',
|
||||
'!significant_text',
|
||||
],
|
||||
},
|
||||
],
|
||||
|
|
|
@ -632,6 +632,7 @@ export const getVis = (bucketType: string) => {
|
|||
'!sampler',
|
||||
'!diversified_sampler',
|
||||
'!multi_terms',
|
||||
'!significant_text',
|
||||
],
|
||||
params: [],
|
||||
},
|
||||
|
@ -648,6 +649,7 @@ export const getVis = (bucketType: string) => {
|
|||
'!sampler',
|
||||
'!diversified_sampler',
|
||||
'!multi_terms',
|
||||
'!significant_text',
|
||||
],
|
||||
params: [],
|
||||
},
|
||||
|
@ -664,6 +666,7 @@ export const getVis = (bucketType: string) => {
|
|||
'!sampler',
|
||||
'!diversified_sampler',
|
||||
'!multi_terms',
|
||||
'!significant_text',
|
||||
],
|
||||
params: [
|
||||
{
|
||||
|
@ -716,6 +719,7 @@ export const getVis = (bucketType: string) => {
|
|||
'!sampler',
|
||||
'!diversified_sampler',
|
||||
'!multi_terms',
|
||||
'!significant_text',
|
||||
],
|
||||
params: [],
|
||||
},
|
||||
|
@ -732,6 +736,7 @@ export const getVis = (bucketType: string) => {
|
|||
'!sampler',
|
||||
'!diversified_sampler',
|
||||
'!multi_terms',
|
||||
'!significant_text',
|
||||
],
|
||||
params: [],
|
||||
},
|
||||
|
@ -748,6 +753,7 @@ export const getVis = (bucketType: string) => {
|
|||
'!sampler',
|
||||
'!diversified_sampler',
|
||||
'!multi_terms',
|
||||
'!significant_text',
|
||||
],
|
||||
params: [
|
||||
{
|
||||
|
@ -771,6 +777,7 @@ export const getVis = (bucketType: string) => {
|
|||
'!sampler',
|
||||
'!diversified_sampler',
|
||||
'!multi_terms',
|
||||
'!significant_text',
|
||||
],
|
||||
params: [],
|
||||
},
|
||||
|
@ -787,6 +794,7 @@ export const getVis = (bucketType: string) => {
|
|||
'!sampler',
|
||||
'!diversified_sampler',
|
||||
'!multi_terms',
|
||||
'!significant_text',
|
||||
],
|
||||
params: [],
|
||||
},
|
||||
|
@ -803,6 +811,7 @@ export const getVis = (bucketType: string) => {
|
|||
'!sampler',
|
||||
'!diversified_sampler',
|
||||
'!multi_terms',
|
||||
'!significant_text',
|
||||
],
|
||||
params: [
|
||||
{
|
||||
|
|
|
@ -156,6 +156,7 @@ export const sampleAreaVis = {
|
|||
'!sampler',
|
||||
'!diversified_sampler',
|
||||
'!multi_terms',
|
||||
'!significant_text',
|
||||
],
|
||||
editor: false,
|
||||
params: [],
|
||||
|
@ -173,6 +174,7 @@ export const sampleAreaVis = {
|
|||
'!sampler',
|
||||
'!diversified_sampler',
|
||||
'!multi_terms',
|
||||
'!significant_text',
|
||||
],
|
||||
editor: false,
|
||||
params: [],
|
||||
|
@ -190,6 +192,7 @@ export const sampleAreaVis = {
|
|||
'!sampler',
|
||||
'!diversified_sampler',
|
||||
'!multi_terms',
|
||||
'!significant_text',
|
||||
],
|
||||
params: [
|
||||
{
|
||||
|
|
|
@ -164,6 +164,7 @@ export const areaVisTypeDefinition = {
|
|||
'!sampler',
|
||||
'!diversified_sampler',
|
||||
'!multi_terms',
|
||||
'!significant_text',
|
||||
],
|
||||
},
|
||||
{
|
||||
|
@ -181,6 +182,7 @@ export const areaVisTypeDefinition = {
|
|||
'!sampler',
|
||||
'!diversified_sampler',
|
||||
'!multi_terms',
|
||||
'!significant_text',
|
||||
],
|
||||
},
|
||||
{
|
||||
|
@ -198,6 +200,7 @@ export const areaVisTypeDefinition = {
|
|||
'!sampler',
|
||||
'!diversified_sampler',
|
||||
'!multi_terms',
|
||||
'!significant_text',
|
||||
],
|
||||
},
|
||||
],
|
||||
|
|
|
@ -167,6 +167,7 @@ export const histogramVisTypeDefinition = {
|
|||
'!sampler',
|
||||
'!diversified_sampler',
|
||||
'!multi_terms',
|
||||
'!significant_text',
|
||||
],
|
||||
},
|
||||
{
|
||||
|
@ -184,6 +185,7 @@ export const histogramVisTypeDefinition = {
|
|||
'!sampler',
|
||||
'!diversified_sampler',
|
||||
'!multi_terms',
|
||||
'!significant_text',
|
||||
],
|
||||
},
|
||||
{
|
||||
|
@ -201,6 +203,7 @@ export const histogramVisTypeDefinition = {
|
|||
'!sampler',
|
||||
'!diversified_sampler',
|
||||
'!multi_terms',
|
||||
'!significant_text',
|
||||
],
|
||||
},
|
||||
],
|
||||
|
|
|
@ -166,6 +166,7 @@ export const horizontalBarVisTypeDefinition = {
|
|||
'!sampler',
|
||||
'!diversified_sampler',
|
||||
'!multi_terms',
|
||||
'!significant_text',
|
||||
],
|
||||
},
|
||||
{
|
||||
|
@ -183,6 +184,7 @@ export const horizontalBarVisTypeDefinition = {
|
|||
'!sampler',
|
||||
'!diversified_sampler',
|
||||
'!multi_terms',
|
||||
'!significant_text',
|
||||
],
|
||||
},
|
||||
{
|
||||
|
@ -200,6 +202,7 @@ export const horizontalBarVisTypeDefinition = {
|
|||
'!sampler',
|
||||
'!diversified_sampler',
|
||||
'!multi_terms',
|
||||
'!significant_text',
|
||||
],
|
||||
},
|
||||
],
|
||||
|
|
|
@ -158,6 +158,7 @@ export const lineVisTypeDefinition = {
|
|||
'!sampler',
|
||||
'!diversified_sampler',
|
||||
'!multi_terms',
|
||||
'!significant_text',
|
||||
],
|
||||
},
|
||||
{
|
||||
|
@ -175,6 +176,7 @@ export const lineVisTypeDefinition = {
|
|||
'!sampler',
|
||||
'!diversified_sampler',
|
||||
'!multi_terms',
|
||||
'!significant_text',
|
||||
],
|
||||
},
|
||||
{
|
||||
|
@ -192,6 +194,7 @@ export const lineVisTypeDefinition = {
|
|||
'!sampler',
|
||||
'!diversified_sampler',
|
||||
'!multi_terms',
|
||||
'!significant_text',
|
||||
],
|
||||
},
|
||||
],
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* 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 expect from '@kbn/expect';
|
||||
import { ExpectExpression, expectExpressionProvider } from './helpers';
|
||||
import { FtrProviderContext } from '../../../functional/ftr_provider_context';
|
||||
|
||||
export default function ({
|
||||
getService,
|
||||
updateBaselines,
|
||||
}: FtrProviderContext & { updateBaselines: boolean }) {
|
||||
let expectExpression: ExpectExpression;
|
||||
|
||||
describe('esaggs_significanttext', () => {
|
||||
before(() => {
|
||||
expectExpression = expectExpressionProvider({ getService, updateBaselines });
|
||||
});
|
||||
|
||||
const timeRange = {
|
||||
from: '2015-09-21T00:00:00Z',
|
||||
to: '2015-09-22T00:00:00Z',
|
||||
};
|
||||
|
||||
describe('aggSignificantText', () => {
|
||||
it('can execute aggSignificantText', async () => {
|
||||
const expression = `
|
||||
kibana_context timeRange={timerange from='${timeRange.from}' to='${timeRange.to}'}
|
||||
| esaggs index={indexPatternLoad id='logstash-*'}
|
||||
aggs={aggSignificantText id="1" enabled=true schema="bucket" field="headings" size=10}
|
||||
aggs={aggCount id="2" enabled=true schema="metric"}
|
||||
`;
|
||||
const result = await expectExpression('sampler', expression).getResponse();
|
||||
|
||||
expect(result.columns.length).to.be(2);
|
||||
const significantTermColumn = result.columns[0];
|
||||
expect(significantTermColumn.name).to.be('Top 10 unusual terms from "headings" text');
|
||||
|
||||
const countColumn = result.columns[1];
|
||||
expect(countColumn.name).to.be('Count');
|
||||
|
||||
expect(result.rows.length).to.be(10);
|
||||
|
||||
expect(result.rows[0]['col-0-1']).to.be('facebook.com');
|
||||
expect(result.rows[0]['col-1-2']).to.be(815);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
|
@ -45,5 +45,6 @@ export default function ({ getService, getPageObjects, loadTestFile }: FtrProvid
|
|||
loadTestFile(require.resolve('./esaggs_timeshift'));
|
||||
loadTestFile(require.resolve('./esaggs_multiterms'));
|
||||
loadTestFile(require.resolve('./esaggs_sampler'));
|
||||
loadTestFile(require.resolve('./esaggs_significanttext'));
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue