import { get } from 'lodash' ; import { escapeForElasticsearchQuery } from '../../../../util/string_utils' ; import { ml } from '../../../../services/ml_api_service' ; interface SplitFieldWithValue { name : string ; value : string ; } type TimeStamp = number ; interface Result { time : TimeStamp ; value : unknown ; } interface ProcessedResults { success : boolean ; results : Record < number , Result [ ] > ; totalResults : number ; } export function getScoresByRecord ( jobId , earliestMs , latestMs , intervalMs , firstSplitField ) { return new Promise ( ( resolve , reject ) => { const obj = { success : true , results : { } , totalResults : 0 , } ; let jobIdFilterStr = 'job_id: ' + jobId ; if ( firstSplitField && firstSplitField . value !== undefined ) { jobIdFilterStr += ` AND ${ escapeForElasticsearchQuery ( firstSplitField . name ) }:` ; jobIdFilterStr += `"${ String ( firstSplitField . value ) . replace ( /\\/g , '\\\\' ) }"` ; } ml . results . anomalySearch ( { size : 0 , body : { query : { bool : { filter : [ { query_string : { query : 'result_type:record' , } , } , { bool : { must : [ { range : { timestamp : { gte : earliestMs , lte : latestMs , format : 'epoch_millis' , } , } , } , { query_string : { query : jobIdFilterStr , } , } , ] , } , } , ] , } , } , aggs : { detector_index : { terms : { field : 'detector_index' , order : { recordScore : 'desc' , } , } , aggs : { recordScore : { max : { field : 'record_score' , } , } , byTime : { date_histogram : { field : 'timestamp' , fixed_interval : `${ intervalMs }ms` , min_doc_count : 1 , extended_bounds : { min : earliestMs , max : latestMs , } , } , aggs : { recordScore : { max : { field : 'record_score' , } , } , } , } , } , } , } , } , } , [ jobId ] ) . then ( ( resp ) => { const detectorsByIndex = get ( resp , [ 'aggregations' , 'detector_index' , 'buckets' ] , [ ] ) ; detectorsByIndex . forEach ( ( dtr ) => { const dtrResults = [ ] ; const dtrIndex = + dtr . key ; const buckets = get ( dtr , [ 'byTime' , 'buckets' ] , [ ] ) ; for ( let j = 0 ; j < buckets . length ; j ++ ) { const bkt = buckets [ j ] ; const time = bkt . key ; dtrResults . push ( { time , value : get ( bkt , [ 'recordScore' , 'value' ] ) , } ) ; } obj . results [ dtrIndex ] = dtrResults ; } ) ; resolve ( obj ) ; } ) . catch ( ( resp ) => { reject ( resp ) ; } ) ; } ) ; }