From 6edabd121616c18ee5e3494ea2daff18faa45026 Mon Sep 17 00:00:00 2001 From: Walter Rafelsberger Date: Tue, 2 Nov 2021 10:25:48 +0100 Subject: [PATCH] [ML] Fix boolean field support. (#116608) Fixes support for boolean field types to be accepted as field candidates for APM correlation and failed transaction analysis. --- .../queries/query_field_candidates.ts | 16 ++++++++++++---- .../queries/query_field_value_pairs.ts | 5 ++++- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/apm/server/lib/search_strategies/queries/query_field_candidates.ts b/x-pack/plugins/apm/server/lib/search_strategies/queries/query_field_candidates.ts index 292be1b5817aa..612225a2348cb 100644 --- a/x-pack/plugins/apm/server/lib/search_strategies/queries/query_field_candidates.ts +++ b/x-pack/plugins/apm/server/lib/search_strategies/queries/query_field_candidates.ts @@ -7,6 +7,8 @@ import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; +import { ES_FIELD_TYPES } from '@kbn/field-types'; + import type { ElasticsearchClient } from 'src/core/server'; import type { SearchStrategyParams } from '../../../../common/search_strategies/types'; @@ -22,6 +24,12 @@ import { hasPrefixToInclude } from '../utils'; import { getQueryWithParams } from './get_query_with_params'; import { getRequestBase } from './get_request_base'; +const SUPPORTED_ES_FIELD_TYPES = [ + ES_FIELD_TYPES.KEYWORD, + ES_FIELD_TYPES.IP, + ES_FIELD_TYPES.BOOLEAN, +]; + export const shouldBeExcluded = (fieldName: string) => { return ( FIELDS_TO_EXCLUDE_AS_CANDIDATE.has(fieldName) || @@ -54,7 +62,7 @@ export const fetchTransactionDurationFieldCandidates = async ( params: SearchStrategyParams ): Promise<{ fieldCandidates: string[] }> => { const { index } = params; - // Get all fields with keyword mapping + // Get all supported fields const respMapping = await esClient.fieldCaps({ index, fields: '*', @@ -64,9 +72,9 @@ export const fetchTransactionDurationFieldCandidates = async ( const acceptableFields: Set = new Set(); Object.entries(respMapping.body.fields).forEach(([key, value]) => { - const fieldTypes = Object.keys(value); - const isSupportedType = fieldTypes.some( - (type) => type === 'keyword' || type === 'ip' + const fieldTypes = Object.keys(value) as ES_FIELD_TYPES[]; + const isSupportedType = fieldTypes.some((type) => + SUPPORTED_ES_FIELD_TYPES.includes(type) ); // Definitely include if field name matches any of the wild card if (hasPrefixToInclude(key) && isSupportedType) { diff --git a/x-pack/plugins/apm/server/lib/search_strategies/queries/query_field_value_pairs.ts b/x-pack/plugins/apm/server/lib/search_strategies/queries/query_field_value_pairs.ts index 39d6aea2f38bd..e57ef5ee341ee 100644 --- a/x-pack/plugins/apm/server/lib/search_strategies/queries/query_field_value_pairs.ts +++ b/x-pack/plugins/apm/server/lib/search_strategies/queries/query_field_value_pairs.ts @@ -60,12 +60,15 @@ const fetchTransactionDurationFieldTerms = async ( resp.body.aggregations .attribute_terms as estypes.AggregationsMultiBucketAggregate<{ key: string; + key_as_string?: string; }> )?.buckets; if (buckets?.length >= 1) { return buckets.map((d) => ({ fieldName, - fieldValue: d.key, + // The terms aggregation returns boolean fields as { key: 0, key_as_string: "false" }, + // so we need to pick `key_as_string` if it's present, otherwise searches on boolean fields would fail later on. + fieldValue: d.key_as_string ?? d.key, })); } } catch (e) {