import { CoreStart } from 'src/core/public' ; import { WorkspaceField , ServerResultNode } from '../types' ; const DEFAULT_SHARD_SIZE = 5000 ; function createSamplerSearchBody ( aggs , shardSize = DEFAULT_SHARD_SIZE ) { return { size : 0 , aggs : { sample : { sampler : { shard_size : shardSize , } , aggs , } , } , } ; } function createTopTermsAggName ( fieldName ) { return `top_values_${ fieldName }` ; } function createTopTermsSubAgg ( field , size = 10 ) { return { [ createTopTermsAggName ( field ) ] : { terms : { field , size , } , } , } ; } interface TopTermsAggResponse { aggregations ? : { sample : Record < string , { buckets : Array < { key : string ; doc_count : number ; } > ; } > ; } ; } function getTopTermsResult ( response , fieldName ) { if ( ! response . aggregations ) { return [ ] ; } return response . aggregations . sample [ createTopTermsAggName ( fieldName ) ] . buckets . map ( ( bucket ) => bucket . key ) ; } export function createServerResultNode ( fieldName , term , allFields ) { const field = allFields . find ( ( { name } ) => name === fieldName ) ; if ( ! field ) { throw new Error ( 'Invariant error: field not found' ) ; } return { field : fieldName , term , id : '' , color : field . color , icon : field . icon , data : { field : fieldName , term , } , label : term , } ; } export async function fetchTopNodes ( post , index , fields ) { const aggs = fields . map ( ( { name } ) => name ) . map ( ( fieldName ) => createTopTermsSubAgg ( fieldName ) ) . reduce ( ( allAggs , subAgg ) => ( { ... allAggs , ... subAgg } ) ) ; const body = createSamplerSearchBody ( aggs ) ; const response = ( await post < { resp : TopTermsAggResponse ; } > ( '../api/graph/searchProxy' , { body : JSON . stringify ( { index , body } ) , } ) ) . resp ; const nodes = [ ] ; fields . forEach ( ( { name } ) => { const topTerms = getTopTermsResult ( response , name ) ; const fieldNodes = topTerms . map ( ( term ) => createServerResultNode ( name , term , fields ) ) ; nodes . push ( ... fieldNodes ) ; } ) ; return nodes ; }