import type { RuntimeMappings } from '../../../../../../../common/types/fields' ; import type { Datafeed , Job } from '../../../../../../../common/types/anomaly_detection_jobs' ; import { isPopulatedObject } from '../../../../../../../common/util/object_utils' ; interface Response { runtime_mappings : RuntimeMappings ; discarded_mappings : RuntimeMappings ; } export function filterRuntimeMappings ( job , datafeed ) { if ( ! ( isPopulatedObject ( datafeed , [ 'runtime_mappings' ] ) && isPopulatedObject ( datafeed . runtime_mappings ) ) ) { return { runtime_mappings : { } , discarded_mappings : { } , } ; } const usedFields = findFieldsInJob ( job , datafeed ) ; const { runtimeMappings , discardedMappings } = createMappings ( datafeed . runtime_mappings , usedFields ) ; return { runtime_mappings : runtimeMappings , discarded_mappings : discardedMappings } ; } function findFieldsInJob ( job , datafeed ) { const usedFields = new Set < string > ( ) ; job . analysis_config . detectors . forEach ( ( d ) => { if ( d . field_name !== undefined ) { usedFields . add ( d . field_name ) ; } if ( d . by_field_name !== undefined ) { usedFields . add ( d . by_field_name ) ; } if ( d . over_field_name !== undefined ) { usedFields . add ( d . over_field_name ) ; } if ( d . partition_field_name !== undefined ) { usedFields . add ( d . partition_field_name ) ; } } ) ; if ( job . analysis_config . categorization_field_name !== undefined ) { usedFields . add ( job . analysis_config . categorization_field_name ) ; } if ( job . analysis_config . summary_count_field_name !== undefined ) { usedFields . add ( job . analysis_config . summary_count_field_name ) ; } if ( job . analysis_config . influencers !== undefined ) { job . analysis_config . influencers . forEach ( ( i ) => usedFields . add ( i ) ) ; } const aggs = datafeed . aggregations ?? datafeed . aggs ; if ( aggs !== undefined ) { findFieldsInAgg ( aggs ) . forEach ( ( f ) => usedFields . add ( f ) ) ; } const query = datafeed . query ; if ( query !== undefined ) { findFieldsInQuery ( query ) . forEach ( ( f ) => usedFields . add ( f ) ) ; } return [ ... usedFields ] ; } function findFieldsInAgg ( obj ) { const fields = [ ] ; Object . entries ( obj ) . forEach ( ( [ key , val ] ) => { if ( isPopulatedObject ( val ) ) { fields . push ( ... findFieldsInAgg ( val ) ) ; } else if ( typeof val === 'string' && key === 'field' ) { fields . push ( val ) ; } } ) ; return fields ; } function findFieldsInQuery ( obj ) { const fields = [ ] ; Object . entries ( obj ) . forEach ( ( [ key , val ] ) => { if ( isPopulatedObject ( val ) ) { fields . push ( key ) ; fields . push ( ... findFieldsInQuery ( val ) ) ; } else if ( typeof val === 'string' ) { fields . push ( val ) ; } else { fields . push ( key ) ; } } ) ; return fields ; } function createMappings ( rm , usedFieldNames ) { return { runtimeMappings : usedFieldNames . reduce ( ( acc , cur ) => { if ( rm [ cur ] !== undefined ) { acc [ cur ] = rm [ cur ] ; } return acc ; } , { } as RuntimeMappings ) , discardedMappings : Object . keys ( rm ) . reduce ( ( acc , cur ) => { if ( usedFieldNames . includes ( cur ) === false && rm [ cur ] !== undefined ) { acc [ cur ] = rm [ cur ] ; } return acc ; } , { } as RuntimeMappings ) , } ; }