From 28a70dadb9d8a26f7a88201f2ca74478f8f3f6f2 Mon Sep 17 00:00:00 2001 From: James Gowdy Date: Wed, 22 Mar 2023 04:51:27 -0400 Subject: [PATCH] [ML] Do not match time series counter fields with aggs in wizards (#153021) Time series counter metric fields are treated as non aggregatable and are not matched with aggregations in the `new_job_caps` endpoint. This removes them from the detector dropdowns in all wizards where we match functions(aggs) to fields. e.g. image Note, the fields are not entirely removed from the `new_job_caps` response. So they are still available in other dropdowns. This fixes an issue where having counter fields available for selection would cause an error. ![](https://user-images.githubusercontent.com/22172091/217270775-402c9081-deab-4c38-9be4-17a80e764dad.png) --- x-pack/plugins/ml/common/util/fields_utils.ts | 4 +++- .../job_service/new_job_caps/field_service.ts | 17 ++++++++++++----- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/x-pack/plugins/ml/common/util/fields_utils.ts b/x-pack/plugins/ml/common/util/fields_utils.ts index f17a593dd09dc..9e0806069a9d3 100644 --- a/x-pack/plugins/ml/common/util/fields_utils.ts +++ b/x-pack/plugins/ml/common/util/fields_utils.ts @@ -60,7 +60,9 @@ export function combineFieldsAndAggs( default: // all other aggs take numerical fields numericalFields.forEach((f) => { - mix(f, a); + if (f.aggregatable) { + mix(f, a); + } }); break; } diff --git a/x-pack/plugins/ml/server/models/job_service/new_job_caps/field_service.ts b/x-pack/plugins/ml/server/models/job_service/new_job_caps/field_service.ts index 4e52a0ddee38d..83144d20b39bc 100644 --- a/x-pack/plugins/ml/server/models/job_service/new_job_caps/field_service.ts +++ b/x-pack/plugins/ml/server/models/job_service/new_job_caps/field_service.ts @@ -10,7 +10,7 @@ import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import type { IScopedClusterClient } from '@kbn/core/server'; import { ES_FIELD_TYPES } from '@kbn/field-types'; import type { DataViewsService } from '@kbn/data-views-plugin/common'; -import type { Field, FieldId, NewJobCaps, RollupFields } from '../../../../common/types/fields'; +import type { Field, NewJobCaps, RollupFields } from '../../../../common/types/fields'; import { combineFieldsAndAggs } from '../../../../common/util/fields_utils'; import { rollupServiceProvider } from './rollup'; import { aggregations, mlOnlyAggregations } from '../../../../common/constants/aggregation_types'; @@ -62,7 +62,7 @@ class FieldsService { this._dataViewsService = dataViewsService; } - private async loadFieldCaps(): Promise { + private async loadFieldCaps() { return await this._mlClusterClient.asCurrentUser.fieldCaps( { index: this._indexPattern, @@ -77,7 +77,7 @@ class FieldsService { const fieldCaps = await this.loadFieldCaps(); const fields: Field[] = []; if (fieldCaps && fieldCaps.fields) { - Object.keys(fieldCaps.fields).forEach((k: FieldId) => { + Object.keys(fieldCaps.fields).forEach((k) => { const fc = fieldCaps.fields[k]; const firstKey = Object.keys(fc)[0]; if (firstKey !== undefined) { @@ -90,8 +90,8 @@ class FieldsService { fields.push({ id: k, name: k, - type: field.type, - aggregatable: field.aggregatable, + type: field.type as ES_FIELD_TYPES, + aggregatable: this.isFieldAggregatable(field), aggs: [], }); } @@ -101,6 +101,13 @@ class FieldsService { return fields.sort((a, b) => a.id.localeCompare(b.id)); } + // check to see whether the field is aggregatable + // If it is a counter field from a time series data stream, we cannot currently + // support any aggregations and so it cannot be used as a field_name in a detector. + private isFieldAggregatable(field: estypes.FieldCapsFieldCapability) { + return field.time_series_metric !== 'counter' ?? field.aggregatable; + } + // public function to load fields from _field_caps and create a list // of aggregations and fields that can be used for an ML job // if the index is a rollup, the fields and aggs will be filtered