diff --git a/controller/search.js b/controller/search.js index 8a61478b..c4c54754 100644 --- a/controller/search.js +++ b/controller/search.js @@ -15,7 +15,8 @@ function setup( backend, query ){ body: query( req.clean ) }; - if ( req.clean.hasOwnProperty('type') ) { + // ? + if( req.clean.hasOwnProperty('type') ){ cmd.type = req.clean.type; } diff --git a/helper/types.js b/helper/types.js index 00a8e5a7..7455476e 100644 --- a/helper/types.js +++ b/helper/types.js @@ -5,7 +5,7 @@ var valid_types = require( '../query/types' ); */ var intersection = function intersection(set1, set2) { return set2.filter(function(value) { - return set1.indexOf(value) !== -1; + return set1.indexOf(value) !== -1; }); }; @@ -38,4 +38,4 @@ module.exports = function calculate_types(clean_types) { if (clean_types.from_address_parser) { return clean_types.from_address_parser; } -}; +}; \ No newline at end of file diff --git a/package.json b/package.json index 3917f1ad..50dc376b 100644 --- a/package.json +++ b/package.json @@ -49,6 +49,7 @@ "pelias-config": "^1.0.1", "pelias-esclient": "0.0.25", "pelias-logger": "^0.0.8", + "pelias-query": "^1.1.0", "pelias-schema": "1.0.0", "pelias-suggester-pipeline": "2.0.2", "stats-lite": "^1.0.3", diff --git a/query/reverse.js b/query/reverse.js index fd835e8f..4e8b13c5 100644 --- a/query/reverse.js +++ b/query/reverse.js @@ -1,33 +1,52 @@ -var queries = require('geopipes-elasticsearch-backend').queries, +var peliasQuery = require('pelias-query'), sort = require('./sort'); -function generate( params ){ +//------------------------------ +// reverse geocode query +//------------------------------ +var query = new peliasQuery.layout.FilteredBooleanQuery(); - var centroid = { - lat: params.lat, - lon: params.lon - }; +// scoring boost +query.sort( peliasQuery.view.sort_distance ); - var query = queries.distance( centroid, { - size: params.size || 1, - sort: true, - distance: '500km' +// non-scoring hard filters +query.filter( peliasQuery.view.boundary_circle ); + +// -------------------------------- + +function generateQuery( clean ){ + + var vs = new peliasQuery.Vars( peliasQuery.defaults ); + + // set defaults + vs.set({ + 'size': 1, + 'boundary:circle:radius': '500km' }); - query.sort = query.sort.concat( sort( params ) ); + // set size + if( clean.size ){ + vs.var( 'size', clean.size ); + } - if ( params.categories && params.categories.length > 0 ) { - addCategoriesFilter( query, params.categories ); + // focus point centroid + if( clean.lat && clean.lon ){ + vs.set({ + // focus point to score by distance + 'focus:point:lat': clean.lat, + 'focus:point:lon': clean.lon, + + // bounding circle + 'boundary:circle:lat': clean.lat, + 'boundary:circle:lon': clean.lon, + }); } - return query; -} + var result = query.render( vs ); -function addCategoriesFilter( query, categories ) { - query.query.filtered.filter.bool.must.push({ - terms: { category: categories } - }); + // @todo: remove this hack + return JSON.parse( JSON.stringify( result ) ); } -module.exports = generate; +module.exports = generateQuery; diff --git a/query/search.js b/query/search.js index 968e9471..244bee4b 100644 --- a/query/search.js +++ b/query/search.js @@ -1,188 +1,161 @@ -var queries = require('geopipes-elasticsearch-backend').queries, +var peliasQuery = require('pelias-query'), sort = require('../query/sort'), - adminFields = require('../helper/adminFields')(), - addressWeights = require('../helper/address_weights'); + adminFields = require('../helper/adminFields')(); +//------------------------------ +// general-purpose search query +//------------------------------ +var query = new peliasQuery.layout.FilteredBooleanQuery(); -function generate( params ){ - var centroid = null; +// mandatory matches +query.score( peliasQuery.view.boundary_country, 'must' ); +query.score( peliasQuery.view.ngrams, 'must' ); - if ( params.lat && params.lon ){ - centroid = { - lat: params.lat, - lon: params.lon - }; - } - - var query = queries.distance( centroid, { size: params.size } ); - var text = params.text; +// scoring boost +query.score( peliasQuery.view.phrase ); +query.score( peliasQuery.view.focus ); - if (params.bbox) { - query = queries.bbox ( centroid, { size: params.size, bbox: params.bbox } ); +// address components +query.score( peliasQuery.view.address('housenumber') ); +query.score( peliasQuery.view.address('street') ); +query.score( peliasQuery.view.address('postcode') ); + +// admin components +query.score( peliasQuery.view.admin('alpha3') ); +query.score( peliasQuery.view.admin('admin0') ); +query.score( peliasQuery.view.admin('admin1') ); +query.score( peliasQuery.view.admin('admin1_abbr') ); +query.score( peliasQuery.view.admin('admin2') ); +query.score( peliasQuery.view.admin('local_admin') ); +query.score( peliasQuery.view.admin('locality') ); +query.score( peliasQuery.view.admin('neighborhood') ); + +// non-scoring hard filters +query.filter( peliasQuery.view.boundary_circle ); +query.filter( peliasQuery.view.boundary_rect ); + +// -------------------------------- + +function generateQuery( clean ){ + + var vs = new peliasQuery.Vars( peliasQuery.defaults ); + + // set input text + vs.var( 'input:name', clean.text ); + + // set size + if( clean.size ){ + vs.var( 'size', clean.size ); } - query.query.filtered.query = { - 'bool': { - 'must': [], - 'should': [] - } - }; - - if (params.parsed_text) { - // update text - if (params.parsed_text.number && params.parsed_text.street) { - text = params.parsed_text.number + ' ' + params.parsed_text.street; - } else if (params.parsed_text.admin_parts) { - text = params.parsed_text.name; - } + // focus point + if( clean.lat && clean.lon ){ + vs.set({ + 'focus:point:lat': clean.lat, + 'focus:point:lon': clean.lon + }); + } - addParsedMatch(query, text, params.parsed_text); + // bbox + if( clean.bbox ){ + vs.set({ + 'boundary:rect:top': clean.bbox.top, + 'boundary:rect:right': clean.bbox.right, + 'boundary:rect:bottom': clean.bbox.bottom, + 'boundary:rect:left': clean.bbox.left + }); } - // add search condition to distance query - query.query.filtered.query.bool.must.push({ - 'match': { - 'name.default': { - 'query': text, - 'analyzer': 'peliasOneEdgeGram' - } + // address parsing + if( clean.parsed_text ){ + + // is it a street address? + var isStreetAddress = clean.parsed_text.hasOwnProperty('number') && clean.parsed_text.hasOwnProperty('street'); + if( isStreetAddress ){ + vs.var( 'input:name', clean.parsed_text.number + ' ' + clean.parsed_text.street ); } - }); - - // add phrase matching query - // note: this is required for shingle/phrase matching - query.query.filtered.query.bool.should.push({ - 'match': { - 'phrase.default': { - 'query': text, - 'analyzer': 'peliasPhrase', - 'type': 'phrase', - 'slop': 2 - } + + // I don't understand this + else if( clean.parsed_text.admin_parts ) { + vs.var( 'input:name', clean.parsed_text.name ); } - }); - query.sort = query.sort.concat( sort( params ) ); + // or this.. + else { + console.warn( 'chaos monkey asks: what happens now?' ); + console.log( clean ); + try{ throw new Error(); } catch(e){ console.error( e.stack ); } // print a stack trace + } - return query; -} + // ==== add parsed matches [address components] ==== -/** - * Traverse the parsed text object, containing all the address parts detected in query string. - * Add matches to query for each identifiable component. - * - * @param {Object} query - * @param {string} defaultText - * @param {Object} parsedText - */ -function addParsedMatch(query, defaultText, parsedText) { - query.query.filtered.query.bool.should = query.query.filtered.query.bool.should || []; - - // copy expected admin fields so we can remove them as we parse the address - var unmatchedAdminFields = adminFields.slice(); - - // address - // number, street, postalcode - addMatch(query, unmatchedAdminFields, 'address.number', parsedText.number, addressWeights.number); - addMatch(query, unmatchedAdminFields, 'address.street', parsedText.street, addressWeights.street); - addMatch(query, unmatchedAdminFields, 'address.zip', parsedText.postalcode, addressWeights.zip); - - // city - // admin2, locality, local_admin, neighborhood - addMatch(query, unmatchedAdminFields, 'admin2', parsedText.city, addressWeights.admin2); - - // state - // admin1, admin1_abbr - addMatch(query, unmatchedAdminFields, 'admin1_abbr', parsedText.state, addressWeights.admin1_abbr); - - // country - // admin0, alpha3 - addMatch(query, unmatchedAdminFields, 'alpha3', parsedText.country, addressWeights.alpha3); - - addUnmatchedAdminFieldsToQuery(query, unmatchedAdminFields, parsedText, defaultText); -} + // house number + if( clean.parsed_text.hasOwnProperty('number') ){ + vs.var( 'input:housenumber', clean.parsed_text.number ); + } -/** - * Check for additional admin fields in the parsed input, and if any was found - * combine into single string and match against all unmatched admin fields. - * - * @param {Object} query - * @param {Array} unmatchedAdminFields - * @param {Object} parsedInput - * @param {string} defaultInput - */ -function addUnmatchedAdminFieldsToQuery(query, unmatchedAdminFields, parsedInput, defaultInput) { - if (unmatchedAdminFields.length === 0 ) { - return; - } + // street name + if( clean.parsed_text.hasOwnProperty('street') ){ + vs.var( 'input:street', clean.parsed_text.street ); + } - var leftovers = []; + // postal code + if( clean.parsed_text.hasOwnProperty('postalcode') ){ + vs.var( 'input:postcode', clean.parsed_text.postalcode ); + } - if (parsedInput.admin_parts) { - leftovers.push(parsedInput.admin_parts); - } - else if (parsedInput.regions) { - leftovers.push(parsedInput.regions); - } + // ==== add parsed matches [admin components] ==== - if (leftovers.length === 0) { - return; - } + // city + if( clean.parsed_text.hasOwnProperty('city') ){ + vs.var( 'input:admin2', clean.parsed_text.city ); + } - leftovers = leftovers.join(' '); + // state + if( clean.parsed_text.hasOwnProperty('state') ){ + vs.var( 'input:admin1_abbr', clean.parsed_text.state ); + } - // if there are additional regions/admin_parts found - if (leftovers !== defaultInput) { - unmatchedAdminFields.forEach(function (key) { - // combine all the leftover parts into one string - addMatch(query, [], key, leftovers); - }); - } -} + // country + if( clean.parsed_text.hasOwnProperty('country') ){ + vs.var( 'input:alpha3', clean.parsed_text.country ); + } -/** - * Add key:value match to query. Apply boost if specified. - * - * @param {Object} query - * @param {Array} unmatched - * @param {string} key - * @param {string|number|undefined} value - * @param {number|undefined} [boost] optional - */ -function addMatch(query, unmatched, key, value, boost) { // jshint ignore:line - if (typeof value === 'undefined') { - return; - } + // ==== deal with the 'leftover' components ==== + // @todo: clean up this code - var match = {}; + // a concept called 'leftovers' which is just 'admin_parts' /or 'regions'. + var leftoversString = ''; + if( clean.parsed_text.hasOwnProperty('admin_parts') ){ + leftoversString = clean.parsed_text.admin_parts; + } + else if( clean.parsed_text.hasOwnProperty('regions') ){ + leftoversString = clean.parsed_text.regions.join(' '); + } - if (boost) { - match[key] = { - query: value, - boost: boost - }; - } - else { - match[key] = value; + // if we have 'leftovers' then assign them to any fields which + // currently don't have a value assigned. + if( leftoversString.length ){ + var unmatchedAdminFields = adminFields.slice(); + + // cycle through fields and set fields which + // are still currently unset + unmatchedAdminFields.forEach( function( key ){ + if( !vs.isset( 'input:' + key ) ){ + vs.var( 'input:' + key, leftoversString ); + } + }); + } } - query.query.filtered.query.bool.should.push({ 'match': match }); + var result = query.render( vs ); - removeFromUnmatched(unmatched, key); -} + // @todo: remove unnessesary sort conditions + result.sort = result.sort.concat( sort( clean ) ); -/** - * If key is found in unmatched list, remove it from the array - * - * @param {Array} unmatched - * @param {string} key - */ -function removeFromUnmatched(unmatched, key) { - var index = unmatched.indexOf(key); - if (index !== -1) { - unmatched.splice(index, 1); - } + // @todo: remove this hack + return JSON.parse( JSON.stringify( result ) ); } -module.exports = generate; +module.exports = generateQuery; diff --git a/sanitiser/_text.js b/sanitiser/_text.js index d8e5a55d..41f38d6c 100644 --- a/sanitiser/_text.js +++ b/sanitiser/_text.js @@ -1,16 +1,17 @@ var isObject = require('is-object'); var query_parser = require('../helper/query_parser'); -// validate inputs, convert types and apply defaults +// validate texts, convert types and apply defaults function sanitize( req ){ req.clean = req.clean || {}; var params= req.query; - // ensure the input params are a valid object + // ensure the text params are a valid object if( !isObject( params ) ){ params = {}; } + // text text if('string' !== typeof params.text || !params.text.length){ return { 'error': true, diff --git a/test/unit/fixture/reverse_standard.js b/test/unit/fixture/reverse_standard.js new file mode 100644 index 00000000..b7cc058f --- /dev/null +++ b/test/unit/fixture/reverse_standard.js @@ -0,0 +1,43 @@ + +module.exports = { + 'query': { + 'filtered': { + 'query': { + 'bool': {} + }, + 'filter': { + 'bool': { + 'must': [ + { + 'geo_distance': { + 'distance': '500km', + 'distance_type': 'plane', + 'optimize_bbox': 'indexed', + '_cache': true, + 'center_point': { + 'lat': 29.49136, + 'lon': -82.50622 + } + } + } + ] + } + } + } + }, + 'sort': [ + '_score', + { + '_geo_distance': { + 'center_point': { + 'lat': 29.49136, + 'lon': -82.50622 + }, + 'order': 'asc', + 'distance_type': 'plane' + } + } + ], + 'size': 1, + 'track_scores': true +}; \ No newline at end of file diff --git a/test/unit/fixture/search_full_address.js b/test/unit/fixture/search_full_address.js new file mode 100644 index 00000000..144dd0ca --- /dev/null +++ b/test/unit/fixture/search_full_address.js @@ -0,0 +1,206 @@ + +var peliasQuery = require('pelias-query'), + vs = new peliasQuery.Vars( peliasQuery.defaults ); + +module.exports = { + 'query': { + 'filtered': { + 'query': { + 'bool': { + 'must': [{ + 'match': { + 'name.default': { + 'query': '123 main st', + 'analyzer': 'peliasOneEdgeGram', + 'boost': 1 + } + } + }], + 'should': [{ + 'match': { + 'phrase.default': { + 'query': '123 main st', + 'analyzer': 'peliasPhrase', + 'type': 'phrase', + 'slop': 2, + 'boost': 1 + } + } + },{ + 'match': { + 'address.number': { + 'query': 123, + 'boost': vs.var('address:housenumber:boost').get(), + 'analyzer': vs.var('address:housenumber:analyzer').get() + } + } + }, { + 'match': { + 'address.street': { + 'query': 'main st', + 'boost': vs.var('address:street:boost').get(), + 'analyzer': vs.var('address:street:analyzer').get() + } + } + }, { + 'match': { + 'address.zip': { + 'query': 10010, + 'boost': vs.var('address:postcode:boost').get(), + 'analyzer': vs.var('address:postcode:analyzer').get() + } + } + }, { + 'match': { + 'alpha3': { + 'query': 'USA', + 'boost': vs.var('admin:alpha3:boost').get(), + 'analyzer': vs.var('admin:alpha3:analyzer').get() + } + } + }, { + 'match': { + 'admin0': { + 'query': 'new york', + 'boost': vs.var('admin:admin0:boost').get(), + 'analyzer': vs.var('admin:admin0:analyzer').get() + } + } + }, { + 'match': { + 'admin1': { + 'query': 'new york', + 'boost': vs.var('admin:admin1:boost').get(), + 'analyzer': vs.var('admin:admin1:analyzer').get() + } + } + }, { + 'match': { + 'admin1_abbr': { + 'query': 'NY', + 'boost': vs.var('admin:admin1_abbr:boost').get(), + 'analyzer': vs.var('admin:admin1_abbr:analyzer').get() + } + } + }, { + 'match': { + 'admin2': { + 'query': 'new york', + 'boost': vs.var('admin:admin2:boost').get(), + 'analyzer': vs.var('admin:admin2:analyzer').get() + } + } + }, { + 'match': { + 'local_admin': { + 'query': 'new york', + 'boost': vs.var('admin:local_admin:boost').get(), + 'analyzer': vs.var('admin:local_admin:analyzer').get() + } + } + }, { + 'match': { + 'locality': { + 'query': 'new york', + 'boost': vs.var('admin:locality:boost').get(), + 'analyzer': vs.var('admin:locality:analyzer').get() + } + } + }, { + 'match': { + 'neighborhood': { + 'query': 'new york', + 'boost': vs.var('admin:neighborhood:boost').get(), + 'analyzer': vs.var('admin:neighborhood:analyzer').get() + } + } + }] + } + }, + 'filter': { + 'bool': { + 'must': [] + } + } + } + }, + 'size': 10, + 'sort': [ + '_score', + { + '_script': { + 'file': 'admin_boost', + 'type': 'number', + 'order': 'desc' + } + }, + { + '_script': { + 'file': 'popularity', + 'type': 'number', + 'order': 'desc' + } + }, + { + '_script': { + 'file': 'population', + 'type': 'number', + 'order': 'desc' + } + }, + { + '_script': { + 'params': { + 'weights': { + 'admin0': 4, + 'admin1': 3, + 'admin2': 2, + 'local_admin': 1, + 'locality': 1, + 'neighborhood': 1 + } + }, + 'file': 'weights', + 'type': 'number', + 'order': 'desc' + } + }, + { + '_script': { + 'params': { + 'category_weights': { + 'transport:air': 2, + 'transport:air:aerodrome': 2, + 'transport:air:airport': 2 + } + }, + 'file': 'category', + 'type': 'number', + 'order': 'desc' + } + }, + { + '_script': { + 'params': { + 'weights': { + 'geoname': 0, + 'address': 4, + 'osmnode': 6, + 'osmway': 6, + 'poi-address': 8, + 'neighborhood': 10, + 'local_admin': 12, + 'locality': 12, + 'admin2': 12, + 'admin1': 14, + 'admin0': 2 + } + }, + 'file': 'weights', + 'type': 'number', + 'order': 'desc' + } + } + ], + 'track_scores': true +}; \ No newline at end of file diff --git a/test/unit/fixture/search_linguistic_bbox.js b/test/unit/fixture/search_linguistic_bbox.js new file mode 100644 index 00000000..69dfe4bb --- /dev/null +++ b/test/unit/fixture/search_linguistic_bbox.js @@ -0,0 +1,50 @@ + +module.exports = { + 'query': { + 'filtered': { + 'query': { + 'bool': { + 'must': [{ + 'match': { + 'name.default': { + 'query': 'test', + 'boost': 1, + 'analyzer': 'peliasOneEdgeGram' + } + } + }], + 'should': [{ + 'match': { + 'phrase.default': { + 'query': 'test', + 'analyzer': 'peliasPhrase', + 'type': 'phrase', + 'boost': 1, + 'slop': 2 + } + } + }] + } + }, + 'filter': { + 'bool': { + 'must': [{ + 'geo_bounding_box': { + 'center_point': { + 'top': 47.47, + 'right': -61.84, + 'bottom': 11.51, + 'left': -103.16 + }, + '_cache': true, + 'type': 'indexed' + } + }] + } + } + } + }, + 'sort': [ '_sort' ], + 'size': 10, + 'track_scores': true +}; \ No newline at end of file diff --git a/test/unit/fixture/search_linguistic_focus.js b/test/unit/fixture/search_linguistic_focus.js new file mode 100644 index 00000000..cceb87fd --- /dev/null +++ b/test/unit/fixture/search_linguistic_focus.js @@ -0,0 +1,68 @@ + +module.exports = { + 'query': { + 'filtered': { + 'query': { + 'bool': { + 'must': [{ + 'match': { + 'name.default': { + 'query': 'test', + 'boost': 1, + 'analyzer': 'peliasOneEdgeGram' + } + } + }], + 'should': [{ + 'match': { + 'phrase.default': { + 'query': 'test', + 'analyzer': 'peliasPhrase', + 'type': 'phrase', + 'boost': 1, + 'slop': 2 + } + } + }, { + 'function_score': { + 'query': { + 'match': { + 'phrase.default': { + 'analyzer': 'peliasPhrase', + 'type': 'phrase', + 'boost': 1, + 'slop': 2, + 'query': 'test' + } + } + }, + 'functions': [{ + 'linear': { + 'center_point': { + 'origin': { + 'lat': 29.49136, + 'lon': -82.50622 + }, + 'offset': '1km', + 'scale': '50km', + 'decay': 0.5 + } + } + }], + 'score_mode': 'avg', + 'boost_mode': 'replace' + } + }] + } + }, + 'filter': { + 'bool': { + 'must': [] + } + } + } + }, + 'sort': [ '_sort' ], + 'size': 10, + 'track_scores': true +}; \ No newline at end of file diff --git a/test/unit/fixture/search_linguistic_focus_bbox.js b/test/unit/fixture/search_linguistic_focus_bbox.js new file mode 100644 index 00000000..d7aa6544 --- /dev/null +++ b/test/unit/fixture/search_linguistic_focus_bbox.js @@ -0,0 +1,79 @@ + +module.exports = { + 'query': { + 'filtered': { + 'query': { + 'bool': { + 'must': [{ + 'match': { + 'name.default': { + 'query': 'test', + 'boost': 1, + 'analyzer': 'peliasOneEdgeGram' + } + } + }], + 'should': [{ + 'match': { + 'phrase.default': { + 'query': 'test', + 'analyzer': 'peliasPhrase', + 'type': 'phrase', + 'boost': 1, + 'slop': 2 + } + } + }, { + 'function_score': { + 'query': { + 'match': { + 'phrase.default': { + 'analyzer': 'peliasPhrase', + 'type': 'phrase', + 'boost': 1, + 'slop': 2, + 'query': 'test' + } + } + }, + 'functions': [{ + 'linear': { + 'center_point': { + 'origin': { + 'lat': 29.49136, + 'lon': -82.50622 + }, + 'offset': '1km', + 'scale': '50km', + 'decay': 0.5 + } + } + }], + 'score_mode': 'avg', + 'boost_mode': 'replace' + } + }] + } + }, + 'filter': { + 'bool': { + 'must': [{ + 'geo_bounding_box': { + 'center_point': { + 'top': 47.47, + 'right': -61.84, + 'bottom': 11.51, + 'left': -103.16 + }, + '_cache': true, + 'type': 'indexed' + } + }] + } + } + } + }, + 'sort': [ '_sort' ], + 'size': 10, + 'track_scores': true +}; \ No newline at end of file diff --git a/test/unit/fixture/search_linguistic_only.js b/test/unit/fixture/search_linguistic_only.js new file mode 100644 index 00000000..a680d3bc --- /dev/null +++ b/test/unit/fixture/search_linguistic_only.js @@ -0,0 +1,39 @@ + +module.exports = { + 'query': { + 'filtered': { + 'query': { + 'bool': { + 'must': [{ + 'match': { + 'name.default': { + 'query': 'test', + 'boost': 1, + 'analyzer': 'peliasOneEdgeGram' + } + } + }], + 'should': [{ + 'match': { + 'phrase.default': { + 'query': 'test', + 'analyzer': 'peliasPhrase', + 'type': 'phrase', + 'boost': 1, + 'slop': 2 + } + } + }] + } + }, + 'filter': { + 'bool': { + 'must': [] + } + } + } + }, + 'sort': [ '_score' ], + 'size': 10, + 'track_scores': true +}; \ No newline at end of file diff --git a/test/unit/fixture/search_partial_address.js b/test/unit/fixture/search_partial_address.js new file mode 100644 index 00000000..eed82e7a --- /dev/null +++ b/test/unit/fixture/search_partial_address.js @@ -0,0 +1,98 @@ + +var peliasQuery = require('pelias-query'), + vs = new peliasQuery.Vars( peliasQuery.defaults ); + +module.exports = { + 'query': { + 'filtered': { + 'query': { + 'bool': { + 'must': [{ + 'match': { + 'name.default': { + 'query': 'soho grand', + 'analyzer': 'peliasOneEdgeGram', + 'boost': 1 + } + } + }], + 'should': [{ + 'match': { + 'phrase.default': { + 'query': 'soho grand', + 'analyzer': 'peliasPhrase', + 'type': 'phrase', + 'slop': 2, + 'boost': 1 + } + } + },{ + 'match': { + 'admin0': { + 'query': 'new york', + 'boost': vs.var('admin:admin0:boost').get(), + 'analyzer': vs.var('admin:admin0:analyzer').get() + } + } + }, { + 'match': { + 'admin1': { + 'query': 'new york', + 'boost': vs.var('admin:admin1:boost').get(), + 'analyzer': vs.var('admin:admin1:analyzer').get() + } + } + }, { + 'match': { + 'admin1_abbr': { + 'query': 'new york', + 'boost': vs.var('admin:admin1_abbr:boost').get(), + 'analyzer': vs.var('admin:admin1_abbr:analyzer').get() + } + } + }, { + 'match': { + 'admin2': { + 'query': 'new york', + 'boost': vs.var('admin:admin2:boost').get(), + 'analyzer': vs.var('admin:admin2:analyzer').get() + } + } + }, { + 'match': { + 'local_admin': { + 'query': 'new york', + 'boost': vs.var('admin:local_admin:boost').get(), + 'analyzer': vs.var('admin:local_admin:analyzer').get() + } + } + }, { + 'match': { + 'locality': { + 'query': 'new york', + 'boost': vs.var('admin:locality:boost').get(), + 'analyzer': vs.var('admin:locality:analyzer').get() + } + } + }, { + 'match': { + 'neighborhood': { + 'query': 'new york', + 'boost': vs.var('admin:neighborhood:boost').get(), + 'analyzer': vs.var('admin:neighborhood:analyzer').get() + } + } + }] + } + }, + 'filter': { + 'bool': { + 'must': [] + } + } + } + }, + 'size': 10, + 'sort': [ '_score' ], + 'track_scores': true +}; \ No newline at end of file diff --git a/test/unit/fixture/search_regions_address.js b/test/unit/fixture/search_regions_address.js new file mode 100644 index 00000000..b0ec4208 --- /dev/null +++ b/test/unit/fixture/search_regions_address.js @@ -0,0 +1,190 @@ + +var peliasQuery = require('pelias-query'), + vs = new peliasQuery.Vars( peliasQuery.defaults ); + +module.exports = { + 'query': { + 'filtered': { + 'query': { + 'bool': { + 'must': [{ + 'match': { + 'name.default': { + 'query': '1 water st', + 'analyzer': 'peliasOneEdgeGram', + 'boost': 1 + } + } + }], + 'should': [{ + 'match': { + 'phrase.default': { + 'query': '1 water st', + 'analyzer': 'peliasPhrase', + 'type': 'phrase', + 'slop': 2, + 'boost': 1 + } + } + },{ + 'match': { + 'address.number': { + 'query': 1, + 'boost': vs.var('address:housenumber:boost').get(), + 'analyzer': vs.var('address:housenumber:analyzer').get() + } + } + }, { + 'match': { + 'address.street': { + 'query': 'water st', + 'boost': vs.var('address:street:boost').get(), + 'analyzer': vs.var('address:street:analyzer').get() + } + } + }, { + 'match': { + 'admin0': { + 'query': 'manhattan', + 'boost': vs.var('admin:admin0:boost').get(), + 'analyzer': vs.var('admin:admin0:analyzer').get() + } + } + }, { + 'match': { + 'admin1': { + 'query': 'manhattan', + 'boost': vs.var('admin:admin1:boost').get(), + 'analyzer': vs.var('admin:admin1:analyzer').get() + } + } + }, { + 'match': { + 'admin1_abbr': { + 'query': 'NY', + 'boost': vs.var('admin:admin1_abbr:boost').get(), + 'analyzer': vs.var('admin:admin1_abbr:analyzer').get() + } + } + }, { + 'match': { + 'admin2': { + 'query': 'manhattan', + 'boost': vs.var('admin:admin2:boost').get(), + 'analyzer': vs.var('admin:admin2:analyzer').get() + } + } + }, { + 'match': { + 'local_admin': { + 'query': 'manhattan', + 'boost': vs.var('admin:local_admin:boost').get(), + 'analyzer': vs.var('admin:local_admin:analyzer').get() + } + } + }, { + 'match': { + 'locality': { + 'query': 'manhattan', + 'boost': vs.var('admin:locality:boost').get(), + 'analyzer': vs.var('admin:locality:analyzer').get() + } + } + }, { + 'match': { + 'neighborhood': { + 'query': 'manhattan', + 'boost': vs.var('admin:neighborhood:boost').get(), + 'analyzer': vs.var('admin:neighborhood:analyzer').get() + } + } + }] + } + }, + 'filter': { + 'bool': { + 'must': [] + } + } + } + }, + 'size': 10, + 'sort': [ + '_score', + { + '_script': { + 'file': 'admin_boost', + 'type': 'number', + 'order': 'desc' + } + }, + { + '_script': { + 'file': 'popularity', + 'type': 'number', + 'order': 'desc' + } + }, + { + '_script': { + 'file': 'population', + 'type': 'number', + 'order': 'desc' + } + }, + { + '_script': { + 'params': { + 'weights': { + 'admin0': 4, + 'admin1': 3, + 'admin2': 2, + 'local_admin': 1, + 'locality': 1, + 'neighborhood': 1 + } + }, + 'file': 'weights', + 'type': 'number', + 'order': 'desc' + } + }, + { + '_script': { + 'params': { + 'category_weights': { + 'transport:air': 2, + 'transport:air:aerodrome': 2, + 'transport:air:airport': 2 + } + }, + 'file': 'category', + 'type': 'number', + 'order': 'desc' + } + }, + { + '_script': { + 'params': { + 'weights': { + 'geoname': 0, + 'address': 4, + 'osmnode': 6, + 'osmway': 6, + 'poi-address': 8, + 'neighborhood': 10, + 'local_admin': 12, + 'locality': 12, + 'admin2': 12, + 'admin1': 14, + 'admin0': 2 + } + }, + 'file': 'weights', + 'type': 'number', + 'order': 'desc' + } + } + ], + 'track_scores': true +}; \ No newline at end of file diff --git a/test/unit/fixture/sort_default.js b/test/unit/fixture/sort_default.js new file mode 100644 index 00000000..255e3b29 --- /dev/null +++ b/test/unit/fixture/sort_default.js @@ -0,0 +1,59 @@ + +var category_weights = require('../../../helper/category_weights'); +var admin_weights = require('../../../helper/admin_weights'); +var weights = require('pelias-suggester-pipeline').weights; + +module.exports = [ + '_score', + { + '_script': { + 'file': 'admin_boost', + 'type': 'number', + 'order': 'desc' + } + }, + { + '_script': { + 'file': 'popularity', + 'type': 'number', + 'order': 'desc' + } + }, + { + '_script': { + 'file': 'population', + 'type': 'number', + 'order': 'desc' + } + }, + { + '_script': { + 'params': { + 'weights': admin_weights + }, + 'file': 'weights', + 'type': 'number', + 'order': 'desc' + } + }, + { + '_script': { + 'params': { + 'category_weights': category_weights.default + }, + 'file': 'category', + 'type': 'number', + 'order': 'desc' + } + }, + { + '_script': { + 'params': { + 'weights': weights + }, + 'file': 'weights', + 'type': 'number', + 'order': 'desc' + } + } +]; \ No newline at end of file diff --git a/test/unit/query/reverse.js b/test/unit/query/reverse.js index e200b832..a8dde064 100644 --- a/test/unit/query/reverse.js +++ b/test/unit/query/reverse.js @@ -1,15 +1,16 @@ var generate = require('../../../query/reverse'); -var admin_boost = 'admin_boost'; -var population = 'population'; -var popularity = 'popularity'; -var category = 'category'; -var category_weights = require('../../../helper/category_weights'); -var admin_weights = require('../../../helper/admin_weights'); -var weights = require('pelias-suggester-pipeline').weights; module.exports.tests = {}; +function debug( a,b ){ + console.log( '----------------------' ); + console.log( JSON.stringify( a, null, 2 ) ); + console.log( '----------------------' ); + console.log( JSON.stringify( b, null, 2 ) ); + console.log( '----------------------' ); +} + module.exports.tests.interface = function(test, common) { test('valid interface', function(t) { t.equal(typeof generate, 'function', 'valid function'); @@ -17,185 +18,25 @@ module.exports.tests.interface = function(test, common) { }); }; -var sort = [ - '_score', - { - '_script': { - 'file': admin_boost, - 'type': 'number', - 'order': 'desc' - } - }, - { - '_script': { - 'file': popularity, - 'type': 'number', - 'order': 'desc' - } - }, - { - '_script': { - 'file': population, - 'type': 'number', - 'order': 'desc' - } - }, - { - '_script': { - 'params': { - 'weights': admin_weights - }, - 'file': 'weights', - 'type': 'number', - 'order': 'desc' - } - }, - { - '_script': { - 'params': { - 'category_weights': category_weights.default - }, - 'file': category, - 'type': 'number', - 'order': 'desc' - } - }, - { - '_script': { - 'params': { - 'weights': weights - }, - 'file': 'weights', - 'type': 'number', - 'order': 'desc' - } - } -]; - module.exports.tests.query = function(test, common) { test('valid query', function(t) { var query = generate({ lat: 29.49136, lon: -82.50622 }); - var expected = { - 'query': { - 'filtered': { - 'query': { - 'match_all': {} - }, - 'filter': { - 'bool': { - 'must': [ - { - 'geo_distance': { - 'distance': '500km', - 'distance_type': 'plane', - 'optimize_bbox': 'indexed', - '_cache': true, - 'center_point': { - 'lat': '29.49', - 'lon': '-82.51' - } - } - } - ] - } - } - } - }, - 'sort': [ - '_score', - { - '_geo_distance': { - 'center_point': { - 'lat': 29.49136, - 'lon': -82.50622 - }, - 'order': 'asc', - 'unit': 'km' - } - } - ].concat(sort.slice(1)), - 'size': 1, - 'track_scores': true - }; - + var expected = require('../fixture/reverse_standard'); t.deepEqual(query, expected, 'valid reverse query'); - + t.end(); + }); + test('size fuzz test', function(t) { // test different sizes var sizes = [1,2,10,undefined,null]; - sizes.forEach( function(size) { - query = generate({ + sizes.forEach( function( size ){ + var query = generate({ lat: 29.49136, lon: -82.50622, size: size }); - expected.size = size ? size : 1; - t.deepEqual(query, expected, 'valid reverse query for size: '+ size); - }); - t.end(); - }); - - test('valid query with categories', function(t) { - var params = { lat: 29.49136, lon: -82.50622, categories: ['food', 'education', 'entertainment'] }; - var query = generate(params); - - var expected = { - 'query': { - 'filtered': { - 'query': { - 'match_all': {} - }, - 'filter': { - 'bool': { - 'must': [ - { - 'geo_distance': { - 'distance': '500km', - 'distance_type': 'plane', - 'optimize_bbox': 'indexed', - '_cache': true, - 'center_point': { - 'lat': '29.49', - 'lon': '-82.51' - } - } - }, - { - 'terms': { - 'category': params.categories - } - } - ] - } - } - } - }, - 'sort': [ - '_score', - { - '_geo_distance': { - 'center_point': { - 'lat': 29.49136, - 'lon': -82.50622 - }, - 'order': 'asc', - 'unit': 'km' - } - } - ].concat(sort.slice(1)), - 'size': 1, - 'track_scores': true - }; - t.deepEqual(query, expected, 'valid reverse query with categories'); - - // test different sizes - var sizes = [1,2,10,undefined,null]; - sizes.forEach( function(size) { - params.size = size; - query = generate(params); - expected.size = size ? size : 1; - t.deepEqual(query, expected, 'valid reverse query for size: '+ size); + t.equal( query.size, size ? size : 1, 'valid reverse query for size: '+ size); }); t.end(); }); diff --git a/test/unit/query/search.js b/test/unit/query/search.js index 79235c78..667fdc26 100644 --- a/test/unit/query/search.js +++ b/test/unit/query/search.js @@ -20,113 +20,10 @@ module.exports.tests.interface = function(test, common) { }); }; -var sort = [ - '_score', - { - '_script': { - 'file': admin_boost, - 'type': 'number', - 'order': 'desc' - } - }, - { - '_script': { - 'file': popularity, - 'type': 'number', - 'order': 'desc' - } - }, - { - '_script': { - 'file': population, - 'type': 'number', - 'order': 'desc' - } - }, - { - '_script': { - 'params': { - 'weights': admin_weights - }, - 'file': 'weights', - 'type': 'number', - 'order': 'desc' - } - }, - { - '_script': { - 'params': { - 'category_weights': category_weights.default - }, - 'file': category, - 'type': 'number', - 'order': 'desc' - } - }, - { - '_script': { - 'params': { - 'weights': weights - }, - 'file': 'weights', - 'type': 'number', - 'order': 'desc' - } - } -]; - -var expected = { - 'query': { - 'filtered': { - 'query': { - 'bool': { - 'must': [{ - 'match': { - 'name.default': { - 'query': 'test', - 'analyzer': 'peliasOneEdgeGram' - } - } - }], - 'should': [{ - 'match': { - 'phrase.default': { - 'query': 'test', - 'analyzer': 'peliasPhrase', - 'type': 'phrase', - 'slop': 2 - } - } - }] - } - }, - 'filter': { - 'bool': { - 'must': [ - { - 'geo_bounding_box': { - 'center_point': { - 'top': '47.47', - 'right': '-61.84', - 'bottom':'11.51', - 'left': '-103.16' - }, - '_cache': true, - 'type': 'indexed' - } - } - ] - } - } - } - }, - 'sort': sort, - 'size': 10, - 'track_scores': true -}; +var sort = require('../fixture/sort_default'); module.exports.tests.query = function(test, common) { - test('valid query', function(t) { + test('valid search + focus + bbox', function(t) { var query = generate({ text: 'test', size: 10, lat: 29.49136, lon: -82.50622, @@ -139,11 +36,14 @@ module.exports.tests.query = function(test, common) { layers: ['test'] }); + var expected = require('../fixture/search_linguistic_focus_bbox'); + expected.sort = sort; + t.deepEqual(query, expected, 'valid search query'); t.end(); }); - test('valid query without lat/lon', function(t) { + test('valid search + bbox', function(t) { var query = generate({ text: 'test', size: 10, bbox: { @@ -154,114 +54,36 @@ module.exports.tests.query = function(test, common) { }, layers: ['test'] }); + + var expected = require('../fixture/search_linguistic_bbox'); + expected.sort = sort; t.deepEqual(query, expected, 'valid search query'); t.end(); }); - test('valid query with no lat/lon and no bbox', function(t) { + test('valid lingustic-only search', function(t) { var query = generate({ text: 'test', size: 10, layers: ['test'] }); - var expected = { - 'query': { - 'filtered': { - 'query': { - 'bool': { - 'must': [{ - 'match': { - 'name.default': { - 'query': 'test', - 'analyzer': 'peliasOneEdgeGram' - } - } - }], - 'should': [{ - 'match': { - 'phrase.default': { - 'query': 'test', - 'analyzer': 'peliasPhrase', - 'type': 'phrase', - 'slop': 2 - } - } - }] - } - }, - 'filter': { - 'bool': { - 'must': [] - } - } - } - }, - 'size': 10, - 'sort': sort, - 'track_scores': true - }; - + var expected = require('../fixture/search_linguistic_only'); + expected.sort = sort; + t.deepEqual(query, expected, 'valid search query'); t.end(); }); - test('valid query without bbox', function(t) { + test('search search + focus', function(t) { var query = generate({ text: 'test', size: 10, lat: 29.49136, lon: -82.50622, layers: ['test'] }); - var expected = { - 'query': { - 'filtered': { - 'query': { - 'bool': { - 'must': [{ - 'match': { - 'name.default': { - 'query': 'test', - 'analyzer': 'peliasOneEdgeGram' - } - } - }], - 'should': [{ - 'match': { - 'phrase.default': { - 'query': 'test', - 'analyzer': 'peliasPhrase', - 'type': 'phrase', - 'slop': 2 - } - } - }] - } - }, - 'filter': { - 'bool': { - 'must': [ - { - 'geo_distance': { - 'distance': '50km', - 'distance_type': 'plane', - 'optimize_bbox': 'indexed', - '_cache': true, - 'center_point': { - 'lat': '29.49', - 'lon': '-82.51' - } - } - } - ] - } - } - } - }, - 'sort': ['_score'].concat(sort.slice(1)), - 'size': 10, - 'track_scores': true - }; + var expected = require('../fixture/search_linguistic_focus'); + expected.sort = sort; t.deepEqual(query, expected, 'valid search query'); t.end(); @@ -269,367 +91,32 @@ module.exports.tests.query = function(test, common) { test('valid query with a full valid address', function(t) { var address = '123 main st new york ny 10010 US'; - var query = generate({ text: address, + var query = generate({ text: address, layers: [ 'geoname', 'osmnode', 'osmway', 'admin0', 'admin1', 'admin2', 'neighborhood', 'locality', 'local_admin', 'osmaddress', 'openaddresses' ], size: 10, details: true, - parsed_text: parser.get_parsed_address(address) + parsed_text: parser.get_parsed_address(address), }); - var expected = { - 'query': { - 'filtered': { - 'query': { - 'bool': { - 'must': [ - { - 'match': { - 'name.default': { - 'query': '123 main st', - 'analyzer': 'peliasOneEdgeGram' - } - } - } - ], - 'should': [ - { - 'match': { - 'address.number': { - 'query': 123, - 'boost': address_weights.number - } - } - }, - { - 'match': { - 'address.street': { - 'query': 'main st', - 'boost': address_weights.street - } - } - }, - { - 'match': { - 'address.zip': { - 'query': 10010, - 'boost': address_weights.zip - } - } - }, - { - 'match': { - 'admin1_abbr': { - 'query': 'NY', - 'boost': address_weights.admin1_abbr - } - } - }, - { - 'match': { - 'alpha3': { - 'query': 'USA', - 'boost': address_weights.alpha3 - } - } - }, - { - match: { - admin0: 'new york' - } - }, - { - match: { - admin1: 'new york' - } - }, - { - match: { - admin2: 'new york' - } - }, - { - match: { - local_admin: 'new york' - } - }, - { - match: { - locality: 'new york' - } - }, - { - match: { - neighborhood: 'new york' - } - }, - { - 'match': { - 'phrase.default': { - 'query': '123 main st', - 'analyzer': 'peliasPhrase', - 'type': 'phrase', - 'slop': 2 - } - } - } - ] - } - }, - 'filter': { - 'bool': { - 'must': [] - } - } - } - }, - 'size': 10, - 'sort': [ - '_score', - { - '_script': { - 'file': 'admin_boost', - 'type': 'number', - 'order': 'desc' - } - }, - { - '_script': { - 'file': 'popularity', - 'type': 'number', - 'order': 'desc' - } - }, - { - '_script': { - 'file': 'population', - 'type': 'number', - 'order': 'desc' - } - }, - { - '_script': { - 'params': { - 'weights': { - 'admin0': 4, - 'admin1': 3, - 'admin2': 2, - 'local_admin': 1, - 'locality': 1, - 'neighborhood': 1 - } - }, - 'file': 'weights', - 'type': 'number', - 'order': 'desc' - } - }, - { - '_script': { - 'params': { - 'category_weights': { - 'transport:air': 2, - 'transport:air:aerodrome': 2, - 'transport:air:airport': 2 - } - }, - 'file': 'category', - 'type': 'number', - 'order': 'desc' - } - }, - { - '_script': { - 'params': { - 'weights': { - 'geoname': 0, - 'address': 4, - 'osmnode': 6, - 'osmway': 6, - 'poi-address': 8, - 'neighborhood': 10, - 'local_admin': 12, - 'locality': 12, - 'admin2': 12, - 'admin1': 14, - 'admin0': 2 - } - }, - 'file': 'weights', - 'type': 'number', - 'order': 'desc' - } - } - ], - 'track_scores': true - }; - + var expected = require('../fixture/search_full_address'); + t.deepEqual(query, expected, 'valid search query'); t.end(); }); test('valid query with partial address', function(t) { var partial_address = 'soho grand, new york'; - var query = generate({ text: partial_address, + var query = generate({ text: partial_address, layers: [ 'geoname', 'osmnode', 'osmway', 'admin0', 'admin1', 'admin2', 'neighborhood', 'locality', 'local_admin', 'osmaddress', 'openaddresses' ], size: 10, details: true, - parsed_text: parser.get_parsed_address(partial_address) + parsed_text: parser.get_parsed_address(partial_address), }); - var expected = { - 'query': { - 'filtered': { - 'query': { - 'bool': { - 'must': [ - { - 'match': { - 'name.default': { - 'query': 'soho grand', - 'analyzer': 'peliasOneEdgeGram' - } - } - } - ], - 'should': [ - { - 'match': { - 'admin0': 'new york' - } - }, - { - 'match': { - 'admin1': 'new york' - } - }, - { - 'match': { - 'admin1_abbr': 'new york' - } - }, - { - 'match': { - 'admin2': 'new york' - } - }, - { - 'match': { - 'local_admin': 'new york' - } - }, - { - 'match': { - 'locality': 'new york' - } - }, - { - 'match': { - 'neighborhood': 'new york' - } - }, - { - 'match': { - 'phrase.default': { - 'query': 'soho grand', - 'analyzer': 'peliasPhrase', - 'type': 'phrase', - 'slop': 2 - } - } - } - ] - } - }, - 'filter': { - 'bool': { - 'must': [] - } - } - } - }, - 'size': 10, - 'sort': [ - '_score', - { - '_script': { - 'file': 'admin_boost', - 'type': 'number', - 'order': 'desc' - } - }, - { - '_script': { - 'file': 'popularity', - 'type': 'number', - 'order': 'desc' - } - }, - { - '_script': { - 'file': 'population', - 'type': 'number', - 'order': 'desc' - } - }, - { - '_script': { - 'params': { - 'weights': { - 'admin0': 4, - 'admin1': 3, - 'admin2': 2, - 'local_admin': 1, - 'locality': 1, - 'neighborhood': 1 - } - }, - 'file': 'weights', - 'type': 'number', - 'order': 'desc' - } - }, - { - '_script': { - 'params': { - 'category_weights': { - 'transport:air': 2, - 'transport:air:aerodrome': 2, - 'transport:air:airport': 2, - 'admin': 2 - } - }, - 'file': 'category', - 'type': 'number', - 'order': 'desc' - } - }, - { - '_script': { - 'params': { - 'weights': { - 'geoname': 0, - 'address': 4, - 'osmnode': 6, - 'osmway': 6, - 'poi-address': 8, - 'neighborhood': 10, - 'local_admin': 12, - 'locality': 12, - 'admin2': 12, - 'admin1': 14, - 'admin0': 2 - } - }, - 'file': 'weights', - 'type': 'number', - 'order': 'desc' - } - } - ], - 'track_scores': true - }; + var expected = require('../fixture/search_partial_address'); + expected.sort = sort; t.deepEqual(query, expected, 'valid search query'); t.end(); @@ -642,179 +129,10 @@ module.exports.tests.query = function(test, common) { 'locality', 'local_admin', 'osmaddress', 'openaddresses' ], size: 10, details: true, - parsed_text: parser.get_parsed_address(partial_address) + parsed_text: parser.get_parsed_address(partial_address), }); - var expected = { - 'query': { - 'filtered': { - 'query': { - 'bool': { - 'must': [ - { - 'match': { - 'name.default': { - 'query': '1 water st', - 'analyzer': 'peliasOneEdgeGram' - } - } - } - ], - 'should': [ - { - 'match': { - 'address.number': { - 'query': 1, - 'boost': address_weights.number - } - } - }, - { - 'match': { - 'address.street': { - 'query': 'water st', - 'boost': address_weights.street - } - } - }, - { - 'match': { - 'admin1_abbr': { - 'query': 'NY', - 'boost': address_weights.admin1_abbr - } - } - }, - { - 'match': { - 'admin0': 'manhattan' - } - }, - { - 'match': { - 'admin1': 'manhattan' - } - }, - { - 'match': { - 'admin2': 'manhattan' - } - }, - { - 'match': { - 'local_admin': 'manhattan' - } - }, - { - 'match': { - 'locality': 'manhattan' - } - }, - { - 'match': { - 'neighborhood': 'manhattan' - } - }, - { - 'match': { - 'phrase.default': { - 'query': '1 water st', - 'analyzer': 'peliasPhrase', - 'type': 'phrase', - 'slop': 2 - } - } - } - ] - } - }, - 'filter': { - 'bool': { - 'must': [] - } - } - } - }, - 'size': 10, - 'sort': [ - '_score', - { - '_script': { - 'file': 'admin_boost', - 'type': 'number', - 'order': 'desc' - } - }, - { - '_script': { - 'file': 'popularity', - 'type': 'number', - 'order': 'desc' - } - }, - { - '_script': { - 'file': 'population', - 'type': 'number', - 'order': 'desc' - } - }, - { - '_script': { - 'params': { - 'weights': { - 'admin0': 4, - 'admin1': 3, - 'admin2': 2, - 'local_admin': 1, - 'locality': 1, - 'neighborhood': 1 - } - }, - 'file': 'weights', - 'type': 'number', - 'order': 'desc' - } - }, - { - '_script': { - 'params': { - 'category_weights': { - 'transport:air': 2, - 'transport:air:aerodrome': 2, - 'transport:air:airport': 2 - } - }, - 'file': 'category', - 'type': 'number', - 'order': 'desc' - } - }, - { - '_script': { - 'params': { - 'weights': { - 'geoname': 0, - 'address': 4, - 'osmnode': 6, - 'osmway': 6, - 'poi-address': 8, - 'neighborhood': 10, - 'local_admin': 12, - 'locality': 12, - 'admin2': 12, - 'admin1': 14, - 'admin0': 2 - } - }, - 'file': 'weights', - 'type': 'number', - 'order': 'desc' - } - } - ], - 'track_scores': true - }; + var expected = require('../fixture/search_regions_address'); t.deepEqual(query, expected, 'valid search query'); t.end(); diff --git a/test/unit/sanitiser/search.js b/test/unit/sanitiser/search.js index d08da111..d0c20f18 100644 --- a/test/unit/sanitiser/search.js +++ b/test/unit/sanitiser/search.js @@ -12,7 +12,7 @@ var search = require('../../../sanitiser/search'), }, size: 10, details: true, - parsed_text: defaultParsed + parsed_text: defaultParsed, }, sanitize = function(query, cb) { _sanitize({'query':query}, cb); }; @@ -70,7 +70,7 @@ module.exports.tests.sanitise_valid_text = function(test, common) { module.exports.tests.sanitize_text_with_delim = function(test, common) { var texts = [ 'a,bcd', '123 main st, admin1', ',,,', ' ' ]; - test('valid texts with a comma', function(t) { + test('valid texts with a comma', function(t) { texts.forEach( function( text ){ sanitize({ text: text }, function( err, clean ){ var expected = JSON.parse(JSON.stringify( defaultClean ));