diff --git a/src/plugins/data/common/search/aggs/utils/get_aggs_formats.ts b/src/plugins/data/common/search/aggs/utils/get_aggs_formats.ts index 5e36fbb791e28..f9b8dd508d4a9 100644 --- a/src/plugins/data/common/search/aggs/utils/get_aggs_formats.ts +++ b/src/plugins/data/common/search/aggs/utils/get_aggs_formats.ts @@ -16,6 +16,7 @@ import { IFieldFormat, SerializedFieldFormat, } from '@kbn/field-formats-plugin/common'; +import { SerializableRecord } from '@kbn/utility-types'; import { DateRange } from '../../expressions'; import { convertDateRangeToString } from '../buckets/lib/date_range'; import { convertIPRangeToString, IpRangeKey } from '../buckets/lib/ip_range'; @@ -35,8 +36,21 @@ type GetFieldFormat = (mapping: SerializedFieldFormat) => IFieldFormat; * @internal */ export function getAggsFormats(getFieldFormat: GetFieldFormat): FieldFormatInstanceType[] { + class FieldFormatWithCache extends FieldFormat { + protected formatCache: Map = new Map(); + + protected getCachedFormat(fieldParams: SerializedFieldFormat<{}, SerializableRecord>) { + const isCached = this.formatCache.has(fieldParams); + const cachedFormat = this.formatCache.get(fieldParams) || getFieldFormat(fieldParams); + if (!isCached) { + this.formatCache.set(fieldParams, cachedFormat); + } + return cachedFormat; + } + } + return [ - class AggsRangeFieldFormat extends FieldFormat { + class AggsRangeFieldFormat extends FieldFormatWithCache { static id = 'range'; static hidden = true; @@ -51,10 +65,7 @@ export function getAggsFormats(getFieldFormat: GetFieldFormat): FieldFormatInsta return range.label; } const nestedFormatter = params as SerializedFieldFormat; - const format = getFieldFormat({ - id: nestedFormatter.id, - params: nestedFormatter.params, - }); + const format = this.getCachedFormat(nestedFormatter); const gte = '\u2265'; const lt = '\u003c'; @@ -88,7 +99,7 @@ export function getAggsFormats(getFieldFormat: GetFieldFormat): FieldFormatInsta }); }; }, - class AggsDateRangeFieldFormat extends FieldFormat { + class AggsDateRangeFieldFormat extends FieldFormatWithCache { static id = 'date_range'; static hidden = true; @@ -98,14 +109,11 @@ export function getAggsFormats(getFieldFormat: GetFieldFormat): FieldFormatInsta } const nestedFormatter = this._params as SerializedFieldFormat; - const format = getFieldFormat({ - id: nestedFormatter.id, - params: nestedFormatter.params, - }); + const format = this.getCachedFormat(nestedFormatter); return convertDateRangeToString(range, format.convert.bind(format)); }; }, - class AggsIpRangeFieldFormat extends FieldFormat { + class AggsIpRangeFieldFormat extends FieldFormatWithCache { static id = 'ip_range'; static hidden = true; @@ -115,20 +123,19 @@ export function getAggsFormats(getFieldFormat: GetFieldFormat): FieldFormatInsta } const nestedFormatter = this._params as SerializedFieldFormat; - const format = getFieldFormat({ - id: nestedFormatter.id, - params: nestedFormatter.params, - }); + const format = this.getCachedFormat(nestedFormatter); return convertIPRangeToString(range, format.convert.bind(format)); }; }, - class AggsTermsFieldFormat extends FieldFormat { + class AggsTermsFieldFormat extends FieldFormatWithCache { static id = 'terms'; static hidden = true; convert = (val: string, type: FieldFormatsContentType) => { const params = this._params; - const format = getFieldFormat({ id: `${params.id}`, params }); + const format = this.getCachedFormat( + params as SerializedFieldFormat<{}, SerializableRecord> + ); if (val === '__other__') { return `${params.otherBucketLabel}`; @@ -141,21 +148,14 @@ export function getAggsFormats(getFieldFormat: GetFieldFormat): FieldFormatInsta }; getConverterFor = (type: FieldFormatsContentType) => (val: string) => this.convert(val, type); }, - class AggsMultiTermsFieldFormat extends FieldFormat { + class AggsMultiTermsFieldFormat extends FieldFormatWithCache { static id = 'multi_terms'; static hidden = true; - private formatCache: Map = new Map(); - convert = (val: unknown, type: FieldFormatsContentType) => { const params = this._params; const formats = (params.paramsPerField as SerializedFieldFormat[]).map((fieldParams) => { - const isCached = this.formatCache.has(fieldParams); - const cachedFormat = this.formatCache.get(fieldParams) || getFieldFormat(fieldParams); - if (!isCached) { - this.formatCache.set(fieldParams, cachedFormat); - } - return cachedFormat; + return this.getCachedFormat(fieldParams); }); if (String(val) === '__other__') {