diff --git a/middleware/trimByGranularity.js b/middleware/trimByGranularity.js index 99a40c90..41e383a4 100644 --- a/middleware/trimByGranularity.js +++ b/middleware/trimByGranularity.js @@ -43,16 +43,31 @@ function isFallbackQuery(results) { }); } -function hasRecordsAtLayers(results, layer) { - return results.some( result => { - return result._matched_queries[0] === 'fallback.' + layer; +// build inverted index which maps 'matched_queries' to documents +// eg. { "fallback.street": [ doc1, doc4, doc8 ] } +function buildInvertedIndex(results) { + let idx = {}; + results.forEach((result, ord) => { + if( _.isArray( result._matched_queries ) ){ + result._matched_queries.forEach( matchedQuery => { + if( !_.isArray( idx[matchedQuery] ) ){ idx[matchedQuery] = []; } + idx[matchedQuery].push( result ); + }); + } }); + return idx; } -function retainRecordsAtLayers(results, layer) { - return results.filter( result => { - return result._matched_queries[0] === 'fallback.' + layer; - }); +// find the most granular possible layer by working through the $layers array in +// order and returning the first one which matches the results. +// note: returns undefined on failure to match any of the layers +function findMostGranularMatchedQuery(idx) { + for( let i=0; i hit._matched_queries ), - filtered: filtered.map( hit => hit._matched_queries ) - }; - logger.debug('[middleware][trimByGranularity]', logInfo); - debugLog.push(req, logInfo); + // remove any documents which don't have a matching fallback layer match. + let filtered = idx[mostGranularMatchedQuery]; - // update data to only contain filtered records - res.data = filtered; + // the filter was applied but the length remained the same, no-op + if( filtered.length === res.data.length ){ return next(); } - // stop iteration upon first successful match - break; - } - } + // logging / debugging + let logInfo = { + unfiltered_length: res.data.length, + filtered_length: filtered.length, + unfiltered: res.data.map( hit => hit._matched_queries ), + filtered: filtered.map( hit => hit._matched_queries ) + }; + logger.debug('[middleware][trimByGranularity]', logInfo); + debugLog.push(req, logInfo); + + // update data to only contain filtered records + res.data = filtered; - next(); + next(); }; }