-
Notifications
You must be signed in to change notification settings - Fork 8.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Maps] Split out agg-descriptors (#83294)
Splits the AggDescriptor into multiple types, to better distinguish Counts from aggs with fields. Corresponding split in agg-classes.
- Loading branch information
1 parent
fe33579
commit 32c3676
Showing
21 changed files
with
465 additions
and
286 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
60 changes: 60 additions & 0 deletions
60
x-pack/plugins/maps/public/classes/fields/agg/agg_field.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
* you may not use this file except in compliance with the Elastic License. | ||
*/ | ||
|
||
import { AggField } from './agg_field'; | ||
import { AGG_TYPE, FIELD_ORIGIN } from '../../../../common/constants'; | ||
import { IESAggSource } from '../../sources/es_agg_source'; | ||
import { IIndexPattern } from 'src/plugins/data/public'; | ||
|
||
const mockIndexPattern = { | ||
title: 'wildIndex', | ||
fields: [ | ||
{ | ||
name: 'foo*', | ||
}, | ||
], | ||
} as IIndexPattern; | ||
|
||
const mockEsAggSource = { | ||
getAggKey: (aggType: AGG_TYPE, fieldName: string) => { | ||
return 'agg_key'; | ||
}, | ||
getAggLabel: (aggType: AGG_TYPE, fieldName: string) => { | ||
return 'agg_label'; | ||
}, | ||
getIndexPattern: async () => { | ||
return mockIndexPattern; | ||
}, | ||
} as IESAggSource; | ||
|
||
const defaultParams = { | ||
label: 'my agg field', | ||
source: mockEsAggSource, | ||
origin: FIELD_ORIGIN.SOURCE, | ||
}; | ||
|
||
describe('supportsFieldMeta', () => { | ||
test('Non-counting aggregations should support field meta', () => { | ||
const avgMetric = new AggField({ ...defaultParams, aggType: AGG_TYPE.AVG }); | ||
expect(avgMetric.supportsFieldMeta()).toBe(true); | ||
const maxMetric = new AggField({ ...defaultParams, aggType: AGG_TYPE.MAX }); | ||
expect(maxMetric.supportsFieldMeta()).toBe(true); | ||
const minMetric = new AggField({ ...defaultParams, aggType: AGG_TYPE.MIN }); | ||
expect(minMetric.supportsFieldMeta()).toBe(true); | ||
const termsMetric = new AggField({ ...defaultParams, aggType: AGG_TYPE.TERMS }); | ||
expect(termsMetric.supportsFieldMeta()).toBe(true); | ||
}); | ||
|
||
test('Counting aggregations should not support field meta', () => { | ||
const sumMetric = new AggField({ ...defaultParams, aggType: AGG_TYPE.SUM }); | ||
expect(sumMetric.supportsFieldMeta()).toBe(false); | ||
const uniqueCountMetric = new AggField({ | ||
...defaultParams, | ||
aggType: AGG_TYPE.UNIQUE_COUNT, | ||
}); | ||
expect(uniqueCountMetric.supportsFieldMeta()).toBe(false); | ||
}); | ||
}); |
78 changes: 78 additions & 0 deletions
78
x-pack/plugins/maps/public/classes/fields/agg/agg_field.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License; | ||
* you may not use this file except in compliance with the Elastic License. | ||
*/ | ||
|
||
import { IndexPattern } from 'src/plugins/data/public'; | ||
import { AGG_TYPE } from '../../../../common/constants'; | ||
import { CountAggField } from './count_agg_field'; | ||
import { isMetricCountable } from '../../util/is_metric_countable'; | ||
import { CountAggFieldParams } from './agg_field_types'; | ||
import { addFieldToDSL, getField } from '../../../../common/elasticsearch_util'; | ||
import { IField } from '../field'; | ||
|
||
const TERMS_AGG_SHARD_SIZE = 5; | ||
|
||
export interface AggFieldParams extends CountAggFieldParams { | ||
esDocField?: IField; | ||
aggType: AGG_TYPE; | ||
} | ||
|
||
export class AggField extends CountAggField { | ||
private readonly _esDocField?: IField; | ||
private readonly _aggType: AGG_TYPE; | ||
|
||
constructor(params: AggFieldParams) { | ||
super(params); | ||
this._esDocField = params.esDocField; | ||
this._aggType = params.aggType; | ||
} | ||
|
||
isValid(): boolean { | ||
return !!this._esDocField; | ||
} | ||
|
||
supportsFieldMeta(): boolean { | ||
// count and sum aggregations are not within field bounds so they do not support field meta. | ||
return !isMetricCountable(this._getAggType()); | ||
} | ||
|
||
canValueBeFormatted(): boolean { | ||
return this._getAggType() !== AGG_TYPE.UNIQUE_COUNT; | ||
} | ||
|
||
_getAggType(): AGG_TYPE { | ||
return this._aggType; | ||
} | ||
|
||
getValueAggDsl(indexPattern: IndexPattern): unknown { | ||
const field = getField(indexPattern, this.getRootName()); | ||
const aggType = this._getAggType(); | ||
const aggBody = aggType === AGG_TYPE.TERMS ? { size: 1, shard_size: TERMS_AGG_SHARD_SIZE } : {}; | ||
return { | ||
[aggType]: addFieldToDSL(aggBody, field), | ||
}; | ||
} | ||
|
||
getRootName(): string { | ||
return this._esDocField ? this._esDocField.getName() : ''; | ||
} | ||
|
||
async getDataType(): Promise<string> { | ||
return this._getAggType() === AGG_TYPE.TERMS ? 'string' : 'number'; | ||
} | ||
|
||
getBucketCount(): number { | ||
// terms aggregation increases the overall number of buckets per split bucket | ||
return this._getAggType() === AGG_TYPE.TERMS ? TERMS_AGG_SHARD_SIZE : 0; | ||
} | ||
|
||
async getOrdinalFieldMetaRequest(): Promise<unknown> { | ||
return this._esDocField ? await this._esDocField.getOrdinalFieldMetaRequest() : null; | ||
} | ||
|
||
async getCategoricalFieldMetaRequest(size: number): Promise<unknown> { | ||
return this._esDocField ? await this._esDocField.getCategoricalFieldMetaRequest(size) : null; | ||
} | ||
} |
22 changes: 22 additions & 0 deletions
22
x-pack/plugins/maps/public/classes/fields/agg/agg_field_types.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License; | ||
* you may not use this file except in compliance with the Elastic License. | ||
*/ | ||
|
||
import { IField } from '../field'; | ||
import { IndexPattern } from '../../../../../../../src/plugins/data/common/index_patterns/index_patterns'; | ||
import { IESAggSource } from '../../sources/es_agg_source'; | ||
import { FIELD_ORIGIN } from '../../../../common/constants'; | ||
|
||
export interface IESAggField extends IField { | ||
getValueAggDsl(indexPattern: IndexPattern): unknown | null; | ||
getBucketCount(): number; | ||
} | ||
|
||
export interface CountAggFieldParams { | ||
label?: string; | ||
source: IESAggSource; | ||
origin: FIELD_ORIGIN; | ||
canReadFromGeoJson?: boolean; | ||
} |
45 changes: 45 additions & 0 deletions
45
x-pack/plugins/maps/public/classes/fields/agg/count_agg_field.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License; | ||
* you may not use this file except in compliance with the Elastic License. | ||
*/ | ||
|
||
import { CountAggField } from './count_agg_field'; | ||
import { AGG_TYPE, FIELD_ORIGIN } from '../../../../common/constants'; | ||
import { IESAggSource } from '../../sources/es_agg_source'; | ||
import { IIndexPattern } from 'src/plugins/data/public'; | ||
|
||
const mockIndexPattern = { | ||
title: 'wildIndex', | ||
fields: [ | ||
{ | ||
name: 'foo*', | ||
}, | ||
], | ||
} as IIndexPattern; | ||
|
||
const mockEsAggSource = { | ||
getAggKey: (aggType: AGG_TYPE, fieldName: string) => { | ||
return 'agg_key'; | ||
}, | ||
getAggLabel: (aggType: AGG_TYPE, fieldName: string) => { | ||
return 'agg_label'; | ||
}, | ||
getIndexPattern: async () => { | ||
return mockIndexPattern; | ||
}, | ||
} as IESAggSource; | ||
|
||
const defaultParams = { | ||
label: 'my agg field', | ||
source: mockEsAggSource, | ||
aggType: AGG_TYPE.COUNT, | ||
origin: FIELD_ORIGIN.SOURCE, | ||
}; | ||
|
||
describe('supportsFieldMeta', () => { | ||
test('Counting aggregations should not support field meta', () => { | ||
const countMetric = new CountAggField({ ...defaultParams }); | ||
expect(countMetric.supportsFieldMeta()).toBe(false); | ||
}); | ||
}); |
100 changes: 100 additions & 0 deletions
100
x-pack/plugins/maps/public/classes/fields/agg/count_agg_field.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License; | ||
* you may not use this file except in compliance with the Elastic License. | ||
*/ | ||
|
||
import { IndexPattern } from 'src/plugins/data/public'; | ||
import { IESAggSource } from '../../sources/es_agg_source'; | ||
import { IVectorSource } from '../../sources/vector_source'; | ||
import { AGG_TYPE, FIELD_ORIGIN } from '../../../../common/constants'; | ||
import { ITooltipProperty, TooltipProperty } from '../../tooltips/tooltip_property'; | ||
import { ESAggTooltipProperty } from '../../tooltips/es_agg_tooltip_property'; | ||
import { IESAggField, CountAggFieldParams } from './agg_field_types'; | ||
|
||
// Agg without field. Essentially a count-aggregation. | ||
export class CountAggField implements IESAggField { | ||
private readonly _source: IESAggSource; | ||
private readonly _origin: FIELD_ORIGIN; | ||
private readonly _label?: string; | ||
private readonly _canReadFromGeoJson: boolean; | ||
|
||
constructor({ label, source, origin, canReadFromGeoJson = true }: CountAggFieldParams) { | ||
this._source = source; | ||
this._origin = origin; | ||
this._label = label; | ||
this._canReadFromGeoJson = canReadFromGeoJson; | ||
} | ||
|
||
_getAggType(): AGG_TYPE { | ||
return AGG_TYPE.COUNT; | ||
} | ||
|
||
getSource(): IVectorSource { | ||
return this._source; | ||
} | ||
|
||
getOrigin(): FIELD_ORIGIN { | ||
return this._origin; | ||
} | ||
|
||
getName(): string { | ||
return this._source.getAggKey(this._getAggType(), this.getRootName()); | ||
} | ||
|
||
getRootName(): string { | ||
return ''; | ||
} | ||
|
||
async getLabel(): Promise<string> { | ||
return this._label | ||
? this._label | ||
: this._source.getAggLabel(this._getAggType(), this.getRootName()); | ||
} | ||
|
||
isValid(): boolean { | ||
return true; | ||
} | ||
|
||
async getDataType(): Promise<string> { | ||
return 'number'; | ||
} | ||
|
||
async createTooltipProperty(value: string | string[] | undefined): Promise<ITooltipProperty> { | ||
const indexPattern = await this._source.getIndexPattern(); | ||
const tooltipProperty = new TooltipProperty(this.getName(), await this.getLabel(), value); | ||
return new ESAggTooltipProperty(tooltipProperty, indexPattern, this, this._getAggType()); | ||
} | ||
|
||
getValueAggDsl(indexPattern: IndexPattern): unknown | null { | ||
return null; | ||
} | ||
|
||
supportsFieldMeta(): boolean { | ||
return false; | ||
} | ||
|
||
getBucketCount() { | ||
return 0; | ||
} | ||
|
||
canValueBeFormatted(): boolean { | ||
return false; | ||
} | ||
|
||
async getOrdinalFieldMetaRequest(): Promise<unknown> { | ||
return null; | ||
} | ||
|
||
async getCategoricalFieldMetaRequest(size: number): Promise<unknown> { | ||
return null; | ||
} | ||
|
||
supportsAutoDomain(): boolean { | ||
return this._canReadFromGeoJson ? true : this.supportsFieldMeta(); | ||
} | ||
|
||
canReadFromGeoJson(): boolean { | ||
return this._canReadFromGeoJson; | ||
} | ||
} |
Oops, something went wrong.