diff --git a/query/autocomplete.js b/query/autocomplete.js index 47aeb87fd..eb8e79fe6 100644 --- a/query/autocomplete.js +++ b/query/autocomplete.js @@ -18,7 +18,7 @@ var views = { boost_exact_matches: require('./view/boost_exact_matches'), max_character_count_layer_filter: require('./view/max_character_count_layer_filter'), focus_point_filter: require('./view/focus_point_distance_filter'), - focus_country: require('./view/focus_country') + focus_multi_match: require('./view/focus_multi_match') }; // add abbrevations for the fields pelias/parser is able to detect. @@ -53,7 +53,8 @@ query.score( views.admin_multi_match_last( adminFields ), 'must'); query.score( peliasQuery.view.focus( peliasQuery.view.leaf.match_all ) ); query.score( peliasQuery.view.popularity( peliasQuery.view.leaf.match_all ) ); query.score( peliasQuery.view.population( peliasQuery.view.leaf.match_all ) ); -query.score( views.focus_country ); +query.score( views.focus_multi_match('focus_country') ); +query.score( views.focus_multi_match('focus_gid') ); query.score( views.custom_boosts( config.get('api.customBoosts') ) ); // non-scoring hard filters @@ -101,6 +102,13 @@ function generateQuery( clean ){ }); } + // focus gid + if( _.isString(clean['focus.gid']) && !_.isEmpty(clean['focus.gid']) ){ + vs.set({ + 'multi_match:focus_gid:input': clean['focus.gid'] + }); + } + // pass the input tokens to the views so they can choose which tokens // are relevant for their specific function. if( _.isArray( clean.tokens ) ){ diff --git a/query/autocomplete_defaults.js b/query/autocomplete_defaults.js index 0d7f8027c..7df8b8ddc 100644 --- a/query/autocomplete_defaults.js +++ b/query/autocomplete_defaults.js @@ -81,6 +81,11 @@ module.exports = _.merge({}, peliasQuery.defaults, { 'multi_match:focus_country:fields': ['parent.country_a', 'parent.dependency_a'], 'multi_match:focus_country:boost': 1.5, + // these options affect the `focus.gid` hard filter + 'multi_match:focus_gid:analyzer': 'standard', + 'multi_match:focus_gid:fields': ['parent.*_id'], + 'multi_match:focus_gid:boost': 1.5, + 'admin:country:analyzer': 'peliasAdmin', 'admin:country:field': 'parent.country.ngram', 'admin:country:boost': 1, diff --git a/query/view/focus_country.js b/query/view/focus_multi_match.js similarity index 81% rename from query/view/focus_country.js rename to query/view/focus_multi_match.js index 463673b4c..cceb4a0c0 100644 --- a/query/view/focus_country.js +++ b/query/view/focus_multi_match.js @@ -1,8 +1,6 @@ const peliasQuery = require('pelias-query'); -module.exports = function (vs) { - const view_name = 'focus_country'; - +module.exports = (view_name) => (vs) => { const input = vs.var(`multi_match:${view_name}:input`).get(); if (!input || input.length < 1) { diff --git a/sanitizer/_countries.js b/sanitizer/_countries.js index 4c6a12744..60583bdf0 100644 --- a/sanitizer/_countries.js +++ b/sanitizer/_countries.js @@ -2,8 +2,7 @@ const _ = require('lodash'); const nonEmptyString = (v) => _.isString(v) && !_.isEmpty(v); const iso3166 = require('../helper/iso3166'); -const _sanitize = (key) => - (raw, clean) => { +const _sanitize = (key) => (raw, clean) => { // error & warning messages const messages = { errors: [], warnings: [] }; diff --git a/sanitizer/_boundary_gid.js b/sanitizer/_gids.js similarity index 64% rename from sanitizer/_boundary_gid.js rename to sanitizer/_gids.js index 4ab914c5b..f921f9a62 100644 --- a/sanitizer/_boundary_gid.js +++ b/sanitizer/_gids.js @@ -1,18 +1,18 @@ const _ = require('lodash'); -function _sanitize(raw, clean) { +const _sanitize = (key) => (raw, clean) => { // error & warning messages var messages = { errors: [], warnings: [] }; // target input param - var boundary_gid = raw['boundary.gid']; + var boundary_gid = raw[`${key}.gid`]; - // param 'boundary.gid' is optional and should not + // param `${key}.gid` is optional and should not // error when simply not set by the user // must be valid string if (!_.isNil(boundary_gid)) { if (!_.isString(boundary_gid) || _.isEmpty(boundary_gid)) { - messages.errors.push('boundary.gid is not a string'); + messages.errors.push(`${key}.gid is not a string`); } else { // boundary gid should take the form of source:layer:id, @@ -22,7 +22,7 @@ function _sanitize(raw, clean) { return x !== ''; }); if ( _.inRange(fields.length, 3, 5) ) { - clean['boundary.gid'] = fields.slice(2).join(':'); + clean[`${key}.gid`] = fields.slice(2).join(':'); } else { messages.errors.push(boundary_gid + ' does not follow source:layer:id format'); @@ -31,13 +31,13 @@ function _sanitize(raw, clean) { } return messages; -} +}; -function _expected(){ - return [{ name: 'boundary.gid' }]; +function _expected(key) { + return () => [{ name: `${key}.gid` }]; } -module.exports = () => ({ - sanitize: _sanitize, - expected: _expected +module.exports = (key = 'boundary') => ({ + sanitize: _sanitize(key), + expected: _expected(key) }); diff --git a/sanitizer/autocomplete.js b/sanitizer/autocomplete.js index cce8f9290..1d3ff4596 100644 --- a/sanitizer/autocomplete.js +++ b/sanitizer/autocomplete.js @@ -22,7 +22,9 @@ const paramGroups = [ ['boundary.circle.lon', 'boundary.circle.lat'], ['boundary.circle.radius'], ['boundary.country'], - ['boundary.gid'] + ['boundary.gid'], + ['focus.country'], + ['focus.gid'] ]; // middleware @@ -45,7 +47,8 @@ module.exports.middleware = (_api_pelias_config) => { focus_country: require('../sanitizer/_countries')('focus'), categories: require('../sanitizer/_categories')(), request_language: require('../sanitizer/_request_language')(), - boundary_gid: require('../sanitizer/_boundary_gid')() + boundary_gid: require('../sanitizer/_gids')('boundary'), + focus_gid: require('../sanitizer/_gids')('focus') }; return ( req, res, next ) => { diff --git a/sanitizer/reverse.js b/sanitizer/reverse.js index 59ed27a29..45705a625 100644 --- a/sanitizer/reverse.js +++ b/sanitizer/reverse.js @@ -37,7 +37,7 @@ module.exports.middleware = (_api_pelias_config) => { geo_reverse: require('../sanitizer/_geo_reverse')(), boundary_country: require('../sanitizer/_countries')('boundary'), request_language: require('../sanitizer/_request_language')(), - boundary_gid: require('../sanitizer/_boundary_gid')() + boundary_gid: require('../sanitizer/_gids')('boundary') }; // middleware diff --git a/sanitizer/search.js b/sanitizer/search.js index 6e4cc409b..f5c3eefbe 100644 --- a/sanitizer/search.js +++ b/sanitizer/search.js @@ -45,7 +45,7 @@ module.exports.middleware = (_api_pelias_config) => { // this can go away once geonames has been abrogated geonames_warnings: require('../sanitizer/_geonames_warnings')(), request_language: require('../sanitizer/_request_language')(), - boundary_gid: require('../sanitizer/_boundary_gid')() + boundary_gid: require('../sanitizer/_gids')('boundary') }; return ( req, res, next ) => { diff --git a/sanitizer/structured_geocoding.js b/sanitizer/structured_geocoding.js index 6ed606c5e..9b1ade590 100644 --- a/sanitizer/structured_geocoding.js +++ b/sanitizer/structured_geocoding.js @@ -51,7 +51,7 @@ module.exports.middleware = (_api_pelias_config) => { boundary_country: require('../sanitizer/_countries')('boundary'), categories: require('../sanitizer/_categories')(), request_language: require('../sanitizer/_request_language')(), - boundary_gid: require('../sanitizer/_boundary_gid')() + boundary_gid: require('../sanitizer/_gids')('boundary') }; return ( req, res, next ) => { diff --git a/test/unit/run.js b/test/unit/run.js index 3856cd9df..45dfb350a 100644 --- a/test/unit/run.js +++ b/test/unit/run.js @@ -103,7 +103,7 @@ var tests = [ require('./sanitizer/_text_pelias_parser'), require('./sanitizer/_tokenizer'), require('./sanitizer/_categories'), - require('./sanitizer/_boundary_gid'), + require('./sanitizer/_gids'), require('./sanitizer/nearby'), require('./sanitizer/autocomplete'), require('./sanitizer/structured_geocoding'), diff --git a/test/unit/sanitizer/_boundary_gid.js b/test/unit/sanitizer/_gids.js similarity index 93% rename from test/unit/sanitizer/_boundary_gid.js rename to test/unit/sanitizer/_gids.js index a53779783..939f5f983 100644 --- a/test/unit/sanitizer/_boundary_gid.js +++ b/test/unit/sanitizer/_gids.js @@ -1,4 +1,5 @@ -var sanitizer = require('../../../sanitizer/_boundary_gid')(); +const gids = require('../../../sanitizer/_gids'); +const sanitizer = gids(); module.exports.tests = {}; @@ -96,6 +97,13 @@ module.exports.tests.sanitize_boundary_gid = function(test, common) { t.end(); }); + test('return an array of expected custom parameters in object form for validation', (t) => { + const expected = [{ name: 'custom-name.gid' }]; + const validParameters = gids('custom-name').expected(); + t.deepEquals(validParameters, expected); + t.end(); + }); + }; module.exports.all = function (tape, common) { diff --git a/test/unit/sanitizer/autocomplete.js b/test/unit/sanitizer/autocomplete.js index e8c9b30eb..d496f3980 100644 --- a/test/unit/sanitizer/autocomplete.js +++ b/test/unit/sanitizer/autocomplete.js @@ -136,10 +136,10 @@ module.exports.tests.sanitizers = function(test, common) { } }; }, - '../sanitizer/_boundary_gid': () => { + '../sanitizer/_gids': (key) => { return { sanitize: () => { - called_sanitizers.push('_boundary_gid'); + called_sanitizers.push(`_${key}_gid`); return { errors: [], warnings: [] }; } }; @@ -163,7 +163,8 @@ module.exports.tests.sanitizers = function(test, common) { '_focus_country', '_categories', '_request_language', - '_boundary_gid' + '_boundary_gid', + '_focus_gid' ]; const req = {}; diff --git a/test/unit/sanitizer/reverse.js b/test/unit/sanitizer/reverse.js index 6ef86fe38..92f8e6e94 100644 --- a/test/unit/sanitizer/reverse.js +++ b/test/unit/sanitizer/reverse.js @@ -102,10 +102,10 @@ module.exports.tests.sanitize = function(test, common) { } }; }, - '../sanitizer/_boundary_gid': () => { + '../sanitizer/_gids': (key) => { return { sanitize: () => { - called_sanitizers.push('_boundary_gid'); + called_sanitizers.push(`_${key}_gid`); return { errors: [], warnings: [] }; } }; diff --git a/test/unit/sanitizer/search.js b/test/unit/sanitizer/search.js index ec092776c..f2506320b 100644 --- a/test/unit/sanitizer/search.js +++ b/test/unit/sanitizer/search.js @@ -134,10 +134,10 @@ module.exports.tests.sanitize = (test, common) => { } }; }, - '../sanitizer/_boundary_gid': () => { + '../sanitizer/_gids': (key) => { return { sanitize: () => { - called_sanitizers.push('_boundary_gid'); + called_sanitizers.push(`_${key}_gid`); return { errors: [], warnings: [] }; } }; diff --git a/test/unit/sanitizer/structured_geocoding.js b/test/unit/sanitizer/structured_geocoding.js index 87894c03d..487015e1a 100644 --- a/test/unit/sanitizer/structured_geocoding.js +++ b/test/unit/sanitizer/structured_geocoding.js @@ -138,10 +138,10 @@ module.exports.tests.sanitize = function(test, common) { } }; }, - '../sanitizer/_boundary_gid': () => { + '../sanitizer/_gids': (key) => { return { sanitize: () => { - called_sanitizers.push('_boundary_gid'); + called_sanitizers.push(`_${key}_gid`); return { errors: [], warnings: [] }; } };