@@ -29,6 +29,11 @@ import converter from 'json-2-csv';
2929import _ from 'lodash' ;
3030import moment from 'moment' ;
3131import { DATA_REPORT_CONFIG } from './constants' ;
32+ import {
33+ buildOpenSearchQuery ,
34+ Filter ,
35+ Query ,
36+ } from '../../../../../src/plugins/data/common' ;
3237
3338export var metaData = {
3439 saved_search_id : < string > null ,
@@ -42,7 +47,7 @@ export var metaData = {
4247 fields_exist : < boolean > false ,
4348 selectedFields : < any > [ ] ,
4449 paternName : < string > null ,
45- filters : < any > [ ] ,
50+ searchSourceJSON : < any > [ ] ,
4651 dateFields : < any > [ ] ,
4752} ;
4853
@@ -65,93 +70,20 @@ export const getSelectedFields = async (columns) => {
6570
6671// Build the OpenSearch query from the meta data
6772// is_count is set to 1 if we building the count query but 0 if we building the fetch data query
68- export const buildQuery = ( report , is_count ) => {
69- let requestBody = esb . boolQuery ( ) ;
70- const filters = report . _source . filters ;
71- for ( let item of JSON . parse ( filters ) . filter ) {
72- if ( item . meta . disabled === false ) {
73- switch ( item . meta . negate ) {
74- case false :
75- switch ( item . meta . type ) {
76- case 'phrase' :
77- requestBody . must (
78- esb . matchPhraseQuery ( item . meta . key , item . meta . params . query )
79- ) ;
80- break ;
81- case 'exists' :
82- requestBody . must ( esb . existsQuery ( item . meta . key ) ) ;
83- break ;
84- case 'phrases' :
85- if ( item . meta . value . indexOf ( ',' ) > - 1 ) {
86- const valueSplit = item . meta . value . split ( ', ' ) ;
87- for ( const [ key , incr ] of valueSplit . entries ( ) ) {
88- requestBody . should ( esb . matchPhraseQuery ( item . meta . key , incr ) ) ;
89- }
90- } else {
91- requestBody . should (
92- esb . matchPhraseQuery ( item . meta . key , item . meta . value )
93- ) ;
94- }
95- requestBody . minimumShouldMatch ( 1 ) ;
96- break ;
97- case 'range' :
98- const builder = esb . rangeQuery ( item . meta . key ) ;
99- if ( item . meta . params . gte ) builder . gte ( item . meta . params . gte ) ;
100- if ( item . meta . params . lte ) builder . lte ( item . meta . params . lte ) ;
101- if ( item . meta . params . gt ) builder . gt ( item . meta . params . gt ) ;
102- if ( item . meta . params . lt ) builder . lt ( item . meta . params . lt ) ;
103- requestBody . must ( builder ) ;
104- break ;
105- }
106- break ;
107- case true :
108- switch ( item . meta . type ) {
109- case 'phrase' :
110- requestBody . mustNot (
111- esb . matchPhraseQuery ( item . meta . key , item . meta . params . query )
112- ) ;
113- break ;
114- case 'exists' :
115- requestBody . mustNot ( esb . existsQuery ( item . meta . key ) ) ;
116- break ;
117- case 'phrases' :
118- let negatedBody = esb . boolQuery ( ) ;
119- if ( item . meta . value . indexOf ( ',' ) > - 1 ) {
120- const valueSplit = item . meta . value . split ( ', ' ) ;
121- for ( const [ key , incr ] of valueSplit . entries ( ) ) {
122- negatedBody . should ( esb . matchPhraseQuery ( item . meta . key , incr ) ) ;
123- }
124- } else {
125- negatedBody . should (
126- esb . matchPhraseQuery ( item . meta . key , item . meta . value )
127- ) ;
128- }
129- negatedBody . minimumShouldMatch ( 1 ) ;
130- requestBody . mustNot ( negatedBody ) ;
131- break ;
132- case 'range' :
133- const builder = esb . rangeQuery ( item . meta . key ) ;
134- if ( item . meta . params . gte ) builder . gte ( item . meta . params . gte ) ;
135- if ( item . meta . params . lte ) builder . lte ( item . meta . params . lte ) ;
136- if ( item . meta . params . gt ) builder . gt ( item . meta . params . gt ) ;
137- if ( item . meta . params . lt ) builder . lt ( item . meta . params . lt ) ;
138- requestBody . mustNot ( builder ) ;
139- break ;
140- }
141- break ;
142- }
143- }
144- }
145- //search part
146- let searchQuery = JSON . parse ( filters )
147- . query . query . replace ( / a n d / g, ' AND ' )
148- . replace ( / o r / g, ' OR ' )
149- . replace ( / n o t / g, ' NOT ' ) ;
150- if ( searchQuery ) {
151- requestBody . must ( esb . queryStringQuery ( searchQuery ) ) ;
152- }
73+ export const buildRequestBody = ( report : any , is_count : number ) => {
74+ let esbBoolQuery = esb . boolQuery ( ) ;
75+ const searchSourceJSON = report . _source . searchSourceJSON ;
76+
77+ const savedObjectQuery : Query = JSON . parse ( searchSourceJSON ) . query ;
78+ const savedObjectFilter : Filter = JSON . parse ( searchSourceJSON ) . filter ;
79+ const QueryFromSavedObject = buildOpenSearchQuery (
80+ undefined ,
81+ savedObjectQuery ,
82+ savedObjectFilter
83+ ) ;
84+ // Add time range
15385 if ( report . _source . timeFieldName && report . _source . timeFieldName . length > 0 ) {
154- requestBody . must (
86+ esbBoolQuery . must (
15587 esb
15688 . rangeQuery ( report . _source . timeFieldName )
15789 . format ( 'epoch_millis' )
@@ -160,36 +92,58 @@ export const buildQuery = (report, is_count) => {
16092 ) ;
16193 }
16294 if ( is_count ) {
163- return esb . requestBodySearch ( ) . query ( requestBody ) ;
95+ return esb . requestBodySearch ( ) . query ( esbBoolQuery ) ;
16496 }
16597
166- //Add the Sort to the query
167- let reqBody = esb . requestBodySearch ( ) . query ( requestBody ) . version ( true ) ;
98+ // Add sorting to the query
99+ let esbSearchQuery = esb
100+ . requestBodySearch ( )
101+ . query ( esbBoolQuery )
102+ . version ( true ) ;
168103
169104 if ( report . _source . sorting . length > 0 ) {
170105 const sortings : Sort [ ] = report . _source . sorting . map ( ( element : string [ ] ) => {
171106 return esb . sort ( element [ 0 ] , element [ 1 ] ) ;
172107 } ) ;
173- reqBody . sorts ( sortings ) ;
108+ esbSearchQuery . sorts ( sortings ) ;
174109 }
175110
176- //get the selected fields only
111+ // add selected fields to query
177112 if ( report . _source . fields_exist ) {
178- reqBody . source ( { includes : report . _source . selectedFields } ) ;
113+ esbSearchQuery . source ( { includes : report . _source . selectedFields } ) ;
179114 }
180- return reqBody ;
115+ // Add a customizer to merge queries to generate request body
116+ let requestBody = _ . mergeWith (
117+ { query : QueryFromSavedObject } ,
118+ esbSearchQuery . toJSON ( ) ,
119+ ( objValue , srcValue ) => {
120+ if ( _ . isArray ( objValue ) ) {
121+ return objValue . concat ( srcValue ) ;
122+ }
123+ }
124+ ) ;
125+
126+ requestBody = addDocValueFields ( report , requestBody ) ;
127+ return requestBody ;
181128} ;
182129
183130// Fetch the data from OpenSearch
184- export const getOpenSearchData = ( arrayHits , report , params , dateFormat : string ) => {
131+ export const getOpenSearchData = (
132+ arrayHits ,
133+ report ,
134+ params ,
135+ dateFormat : string
136+ ) => {
185137 let hits : any = [ ] ;
186138 for ( let valueRes of arrayHits ) {
187139 for ( let data of valueRes . hits ) {
188140 const fields = data . fields ;
189141 // get all the fields of type date and format them to excel format
190142 for ( let dateType of report . _source . dateFields ) {
191143 if ( data . _source [ dateType ] ) {
192- data . _source [ dateType ] = moment ( fields [ dateType ] [ 0 ] ) . format ( dateFormat ) ;
144+ data . _source [ dateType ] = moment ( fields [ dateType ] [ 0 ] ) . format (
145+ dateFormat
146+ ) ;
193147 }
194148 }
195149 delete data [ 'fields' ] ;
@@ -274,3 +228,20 @@ function sanitize(doc: any) {
274228 }
275229 return doc ;
276230}
231+
232+ const addDocValueFields = ( report : any , requestBody : any ) => {
233+ const docValues = [ ] ;
234+ for ( const dateType of report . _source . dateFields ) {
235+ docValues . push ( {
236+ field : dateType ,
237+ format : 'date_hour_minute_second_fraction' ,
238+ } ) ;
239+ }
240+ // elastic-builder doesn't provide function to build docvalue_fields with format,
241+ // this is a workaround which appends docvalues field to the request body.
242+ requestBody = {
243+ ...requestBody ,
244+ docvalue_fields : docValues ,
245+ } ;
246+ return requestBody ;
247+ } ;
0 commit comments