@@ -102,6 +102,87 @@ const buildEsFullTextQuery = (keyword, matchType, singleFieldName) => {
102102 } ;
103103} ;
104104
105+ /**
106+ * Build ES query search request body based on value, keyword, matchType and fieldName
107+ *
108+ * @param {String } value the value to build request body for
109+ * @param {String } keyword the keyword to query
110+ * @param {String } matchType wildcard match or exact match
111+ * @param {Array } fieldName the fieldName
112+ * @return {Object } search request body that can be passed to .search api call
113+ */
114+ const buildEsQueryWithFilter = ( value , keyword , matchType , fieldName ) => {
115+ let should = [ ] ;
116+ if ( value !== 'details' && value !== 'customer' && value !== 'manager' ) {
117+ should = _ . concat ( should , {
118+ query_string : {
119+ query : keyword ,
120+ analyze_wildcard : ( matchType === MATCH_TYPE_WILDCARD ) ,
121+ fields : fieldName ,
122+ } ,
123+ } ) ;
124+ }
125+
126+ if ( value === 'details' ) {
127+ should = _ . concat ( should , {
128+ nested : {
129+ path : 'details' ,
130+ query : {
131+ nested : {
132+ path : 'details.utm' ,
133+ query : {
134+ query_string : {
135+ query : keyword ,
136+ analyze_wildcard : ( matchType === MATCH_TYPE_WILDCARD ) ,
137+ fields : fieldName ,
138+ } ,
139+ } ,
140+ } ,
141+ } ,
142+ } ,
143+ } ) ;
144+ }
145+
146+ if ( value === 'customer' || value === 'manager' ) {
147+ should = _ . concat ( should , {
148+ nested : {
149+ path : 'members' ,
150+ query : {
151+ bool : {
152+ must : [
153+ { match : { 'members.role' : value } } ,
154+ {
155+ query_string : {
156+ query : keyword ,
157+ analyze_wildcard : ( matchType === MATCH_TYPE_WILDCARD ) ,
158+ fields : fieldName ,
159+ } ,
160+ } ,
161+ ] ,
162+ } ,
163+ } ,
164+ } ,
165+ } ) ;
166+ }
167+
168+ return should ;
169+ } ;
170+
171+ /**
172+ * Prepare search request body based on wildcard query
173+ *
174+ * @param {String } value the value to build request body for
175+ * @param {String } keyword the keyword to query
176+ * @param {Array } fieldName the fieldName
177+ * @return {Object } search request body that can be passed to .search api call
178+ */
179+ const setFilter = ( value , keyword , fieldName ) => {
180+ if ( keyword . indexOf ( '*' ) > - 1 ) {
181+ return buildEsQueryWithFilter ( value , keyword , MATCH_TYPE_WILDCARD , fieldName ) ;
182+ }
183+ return buildEsQueryWithFilter ( value , keyword , MATCH_TYPE_EXACT_PHRASE , fieldName ) ;
184+ } ;
185+
105186/**
106187 * Parse the ES search criteria and prepare search request body
107188 *
@@ -152,13 +233,40 @@ const parseElasticSearchCriteria = (criteria, fields, order) => {
152233 }
153234 // prepare the elasticsearch filter criteria
154235 const boolQuery = [ ] ;
236+ let mustQuery = [ ] ;
155237 let fullTextQuery ;
156238 if ( _ . has ( criteria , 'filters.id.$in' ) ) {
157239 boolQuery . push ( {
158240 ids : {
159241 values : criteria . filters . id . $in ,
160242 } ,
161243 } ) ;
244+ } else if ( _ . has ( criteria , 'filters.id' ) ) {
245+ boolQuery . push ( {
246+ term : {
247+ id : criteria . filters . id ,
248+ } ,
249+ } ) ;
250+ }
251+
252+ if ( _ . has ( criteria , 'filters.name' ) ) {
253+ mustQuery = _ . concat ( mustQuery , setFilter ( 'name' , criteria . filters . name , [ 'name' ] ) ) ;
254+ }
255+
256+ if ( _ . has ( criteria , 'filters.code' ) ) {
257+ mustQuery = _ . concat ( mustQuery , setFilter ( 'details' , criteria . filters . code , [ 'details.utm.code' ] ) ) ;
258+ }
259+
260+ if ( _ . has ( criteria , 'filters.customer' ) ) {
261+ mustQuery = _ . concat ( mustQuery , setFilter ( 'customer' ,
262+ criteria . filters . customer ,
263+ [ 'members.firstName' , 'members.lastName' ] ) ) ;
264+ }
265+
266+ if ( _ . has ( criteria , 'filters.manager' ) ) {
267+ mustQuery = _ . concat ( mustQuery , setFilter ( 'manager' ,
268+ criteria . filters . manager ,
269+ [ 'members.firstName' , 'members.lastName' ] ) ) ;
162270 }
163271
164272 if ( _ . has ( criteria , 'filters.status.$in' ) ) {
@@ -222,7 +330,7 @@ const parseElasticSearchCriteria = (criteria, fields, order) => {
222330
223331 if ( ! keyword ) {
224332 // Not a specific field search nor an exact phrase search, do a wildcard match
225- keyword = escapeEsKeyword ( criteria . filters . keyword ) ;
333+ keyword = criteria . filters . keyword ;
226334 matchType = MATCH_TYPE_WILDCARD ;
227335 }
228336
@@ -234,17 +342,22 @@ const parseElasticSearchCriteria = (criteria, fields, order) => {
234342 filter : boolQuery ,
235343 } ;
236344 }
345+
346+ if ( mustQuery . length > 0 ) {
347+ body . query . bool = _ . merge ( body . query . bool , {
348+ must : mustQuery ,
349+ } ) ;
350+ }
237351 if ( fullTextQuery ) {
238352 body . query = _ . merge ( body . query , fullTextQuery ) ;
239353 if ( body . query . bool ) {
240354 body . query . bool . minimum_should_match = 1 ;
241355 }
242356 }
243357
244- if ( fullTextQuery || boolQuery . length > 0 ) {
358+ if ( fullTextQuery || boolQuery . length > 0 || mustQuery . length > 0 ) {
245359 searchCriteria . body = body ;
246360 }
247-
248361 return searchCriteria ;
249362} ;
250363
@@ -267,8 +380,7 @@ const retrieveProjects = (req, criteria, sort, ffields) => {
267380 fields . projects . push ( 'id' ) ;
268381 }
269382
270- const searchCriteria = parseElasticSearchCriteria ( criteria , fields , order ) ;
271-
383+ const searchCriteria = parseElasticSearchCriteria ( criteria , fields , order ) || { } ;
272384 return new Promise ( ( accept , reject ) => {
273385 const es = util . getElasticSearchClient ( ) ;
274386 es . search ( searchCriteria ) . then ( ( docs ) => {
@@ -300,7 +412,8 @@ module.exports = [
300412 'name' , 'name asc' , 'name desc' ,
301413 'type' , 'type asc' , 'type desc' ,
302414 ] ;
303- if ( ! util . isValidFilter ( filters , [ 'id' , 'status' , 'type' , 'memberOnly' , 'keyword' ] ) ||
415+ if ( ! util . isValidFilter ( filters ,
416+ [ 'id' , 'status' , 'memberOnly' , 'keyword' , 'type' , 'name' , 'code' , 'customer' , 'manager' ] ) ||
304417 ( sort && _ . indexOf ( sortableProps , sort ) < 0 ) ) {
305418 return util . handleError ( 'Invalid filters or sort' , null , req , next ) ;
306419 }
0 commit comments