diff --git a/app.js b/app.js index d499c283..047aa903 100644 --- a/app.js +++ b/app.js @@ -3,7 +3,6 @@ var app = require('express')(); /** ----------------------- middleware ----------------------- **/ -app.use( require('./middleware/toobusy') ); // should be first app.use( require('./middleware/headers') ); app.use( require('./middleware/cors') ); app.use( require('./middleware/jsonp') ); diff --git a/helper/geojsonify.js b/helper/geojsonify.js index e28a617c..947c78a0 100644 --- a/helper/geojsonify.js +++ b/helper/geojsonify.js @@ -22,7 +22,6 @@ function search( docs ){ // provide metadata to consumer output.id = doc._id; - output.type = doc._type; output.layer = doc._type; // map center_point diff --git a/middleware/toobusy.js b/middleware/toobusy.js deleted file mode 100644 index bbe6784f..00000000 --- a/middleware/toobusy.js +++ /dev/null @@ -1,19 +0,0 @@ - -// middleware which blocks requests when the eventloop is too busy -var toobusy = require('toobusy'); - -function middleware(req, res, next){ - if( toobusy() ){ - res.status(503); // Service Unavailable - return next('Server Overwhelmed'); - } - return next(); -} - -// calling .shutdown allows your process to exit normally -process.on('SIGINT', function() { - toobusy.shutdown(); - process.exit(); -}); - -module.exports = middleware; \ No newline at end of file diff --git a/package.json b/package.json index 41bde4b6..7a541a0b 100644 --- a/package.json +++ b/package.json @@ -39,8 +39,7 @@ "geopipes-elasticsearch-backend": "0.0.11", "pelias-suggester-pipeline": "2.0.2", "is-object": "^1.0.1", - "pelias-esclient": "0.0.25", - "toobusy": "^0.2.4" + "pelias-esclient": "0.0.25" }, "devDependencies": { "ciao": "^0.3.4", diff --git a/query/search.js b/query/search.js index 9d9916d3..65551cde 100644 --- a/query/search.js +++ b/query/search.js @@ -22,12 +22,28 @@ function generate( params ){ // add search condition to distance query query.query.filtered.query = { - query_string : { - query: params.input, - fields: ['name.default'], - default_operator: 'OR' + 'bool': { + 'must': [{ + 'match': { + 'name.default': params.input + } + } + ] } }; + + if (params.input_admin) { + var admin_fields = ['admin0', 'admin1', 'admin1_abbr', 'admin2', 'alpha3']; + query.query.filtered.query.bool.should = []; + + admin_fields.forEach(function(admin_field) { + var match = {}; + match[admin_field] = params.input_admin; + query.query.filtered.query.bool.should.push({ + 'match': match + }); + }); + } query.sort = query.sort.concat(sort); diff --git a/query/sort.js b/query/sort.js index d79f39b8..2ad6ad5e 100644 --- a/query/sort.js +++ b/query/sort.js @@ -1,8 +1,16 @@ +var admin_boost = 'admin_boost'; var population = 'population'; var popularity = 'popularity'; var weights = require('pelias-suggester-pipeline').weights; module.exports = [ + { + '_script': { + 'file': admin_boost, + 'type': 'number', + 'order': 'desc' + } + }, { '_script': { 'file': population, diff --git a/sanitiser/_input.js b/sanitiser/_input.js index 436c0c73..b1de5e63 100644 --- a/sanitiser/_input.js +++ b/sanitiser/_input.js @@ -3,6 +3,7 @@ function sanitize( req ){ req.clean = req.clean || {}; var params= req.query; + var delim = ','; // ensure the input params are a valid object if( Object.prototype.toString.call( params ) !== '[object Object]' ){ @@ -16,8 +17,17 @@ function sanitize( req ){ 'message': 'invalid param \'input\': text length, must be >0' }; } + req.clean.input = params.input; + // for admin matching during query time + // split 'flatiron, new york, ny' into 'flatiron' and 'new york, ny' + var delim_index = params.input.indexOf(delim); + if ( delim_index !== -1 ) { + req.clean.input = params.input.substring(0, delim_index); + req.clean.input_admin = params.input.substring(delim_index + 1).trim(); + } + return { 'error': false }; } diff --git a/test/unit/controller/doc.js b/test/unit/controller/doc.js index 02090257..6bf4eaba 100644 --- a/test/unit/controller/doc.js +++ b/test/unit/controller/doc.js @@ -24,7 +24,6 @@ module.exports.tests.functional_success = function(test, common) { }, properties: { id: 'myid1', - type: 'mytype1', layer: 'mytype1', name: 'test name1', admin0: 'country1', @@ -40,7 +39,6 @@ module.exports.tests.functional_success = function(test, common) { }, properties: { id: 'myid2', - type: 'mytype2', layer: 'mytype2', name: 'test name2', admin0: 'country2', diff --git a/test/unit/controller/search.js b/test/unit/controller/search.js index 7fd53ccb..3fc6e1a6 100644 --- a/test/unit/controller/search.js +++ b/test/unit/controller/search.js @@ -25,7 +25,6 @@ module.exports.tests.functional_success = function(test, common) { }, properties: { id: 'myid1', - type: 'mytype1', layer: 'mytype1', name: 'test name1', admin0: 'country1', @@ -41,7 +40,6 @@ module.exports.tests.functional_success = function(test, common) { }, properties: { id: 'myid2', - type: 'mytype2', layer: 'mytype2', name: 'test name2', admin0: 'country2', diff --git a/test/unit/controller/suggest.js b/test/unit/controller/suggest.js index 8f04edd7..aded731b 100644 --- a/test/unit/controller/suggest.js +++ b/test/unit/controller/suggest.js @@ -25,7 +25,6 @@ module.exports.tests.functional_success = function(test, common) { }, properties: { id: 'myid1', - type: 'mytype1', layer: 'mytype1', name: 'test name1', admin0: 'country1', @@ -41,7 +40,6 @@ module.exports.tests.functional_success = function(test, common) { }, properties: { id: 'myid2', - type: 'mytype2', layer: 'mytype2', name: 'test name2', admin0: 'country2', diff --git a/test/unit/helper/geojsonify.js b/test/unit/helper/geojsonify.js index f1ec5fcb..be15acec 100644 --- a/test/unit/helper/geojsonify.js +++ b/test/unit/helper/geojsonify.js @@ -114,7 +114,6 @@ module.exports.tests.search = function(test, common) { }, 'properties': { 'id': 'id1', - 'type': 'type1', 'layer': 'type1', 'text': '\'Round Midnight Jazz and Blues Bar, test3, Angel', 'name': '\'Round Midnight Jazz and Blues Bar', @@ -139,7 +138,6 @@ module.exports.tests.search = function(test, common) { }, 'properties': { 'id': 'id2', - 'type': 'type2', 'layer': 'type2', 'text': 'Blues Cafe, test3, Smithfield', 'name': 'Blues Cafe', @@ -164,7 +162,6 @@ module.exports.tests.search = function(test, common) { }, 'properties': { 'id': '34633854', - 'type': 'osmway', 'layer': 'osmway', 'text': 'Empire State Building, Manhattan, NY', 'name': 'Empire State Building', diff --git a/test/unit/query/reverse.js b/test/unit/query/reverse.js index 08550c71..0380fb85 100644 --- a/test/unit/query/reverse.js +++ b/test/unit/query/reverse.js @@ -1,5 +1,6 @@ var generate = require('../../../query/reverse'); +var admin_boost = 'admin_boost'; var population = 'population'; var popularity = 'popularity'; var weights = require('pelias-suggester-pipeline').weights; @@ -15,6 +16,13 @@ module.exports.tests.interface = function(test, common) { var sort = [ '_score', + { + '_script': { + 'file': admin_boost, + 'type': 'number', + 'order': 'desc' + } + }, { '_script': { 'file': population, diff --git a/test/unit/query/search.js b/test/unit/query/search.js index d47246b6..1e5301e3 100644 --- a/test/unit/query/search.js +++ b/test/unit/query/search.js @@ -1,5 +1,6 @@ var generate = require('../../../query/search'); +var admin_boost = 'admin_boost'; var population = 'population'; var popularity = 'popularity'; var weights = require('pelias-suggester-pipeline').weights; @@ -15,6 +16,13 @@ module.exports.tests.interface = function(test, common) { var sort = [ '_score', + { + '_script': { + 'file': admin_boost, + 'type': 'number', + 'order': 'desc' + } + }, { '_script': { 'file': population, @@ -59,12 +67,13 @@ module.exports.tests.query = function(test, common) { 'query': { 'filtered': { 'query': { - 'query_string': { - 'query': 'test', - 'fields': [ - 'name.default' - ], - 'default_operator': 'OR' + 'bool': { + 'must': [{ + 'match': { + 'name.default': 'test' + } + } + ] } }, 'filter': { @@ -111,12 +120,13 @@ module.exports.tests.query = function(test, common) { 'query': { 'filtered': { 'query': { - 'query_string': { - 'query': 'test', - 'fields': [ - 'name.default' - ], - 'default_operator': 'OR' + 'bool': { + 'must': [{ + 'match': { + 'name.default': 'test' + } + } + ] } }, 'filter': { @@ -157,12 +167,13 @@ module.exports.tests.query = function(test, common) { 'query': { 'filtered': { 'query': { - 'query_string': { - 'query': 'test', - 'fields': [ - 'name.default' - ], - 'default_operator': 'OR' + 'bool': { + 'must': [{ + 'match': { + 'name.default': 'test' + } + } + ] } }, 'filter': { @@ -192,12 +203,13 @@ module.exports.tests.query = function(test, common) { 'query': { 'filtered': { 'query': { - 'query_string': { - 'query': 'test', - 'fields': [ - 'name.default' - ], - 'default_operator': 'OR' + 'bool': { + 'must': [{ + 'match': { + 'name.default': 'test' + } + } + ] } }, 'filter': { diff --git a/test/unit/query/sort.js b/test/unit/query/sort.js index 95e2a02e..37d1590d 100644 --- a/test/unit/query/sort.js +++ b/test/unit/query/sort.js @@ -14,6 +14,13 @@ module.exports.tests.interface = function(test, common) { }; var expected = [ + { + '_script': { + 'file': 'admin_boost', + 'type': 'number', + 'order': 'desc' + } + }, { '_script': { 'file': population, diff --git a/test/unit/sanitiser/suggest.js b/test/unit/sanitiser/suggest.js index 6ea903e5..a576f6de 100644 --- a/test/unit/sanitiser/suggest.js +++ b/test/unit/sanitiser/suggest.js @@ -2,6 +2,7 @@ var suggest = require('../../../sanitiser/suggest'), _sanitize = suggest.sanitize, middleware = suggest.middleware, + delim = ',', defaultError = 'invalid param \'input\': text length, must be >0', defaultClean = { input: 'test', lat:0, @@ -54,6 +55,29 @@ module.exports.tests.sanitize_input = function(test, common) { }); }; +module.exports.tests.sanitize_input_with_delim = function(test, common) { + var inputs = [ 'a,bcd', '123 main st, admin1', ',,,', ' ' ]; + + test('valid inputs with a comma', function(t) { + inputs.forEach( function( input ){ + sanitize({ input: input, lat: 0, lon: 0 }, function( err, clean ){ + var expected = JSON.parse(JSON.stringify( defaultClean )); + expected.input = input; + + var delim_index = input.indexOf(delim); + if (delim_index!==-1) { + expected.input = input.substring(0, input.indexOf(delim)); + expected.input_admin = input.substring(delim_index + 1).trim(); + } + + t.equal(err, undefined, 'no error'); + t.deepEqual(clean, expected, 'clean set correctly (' + input + ')'); + }); + }); + t.end(); + }); +}; + module.exports.tests.sanitize_lat = function(test, common) { var lats = { invalid: [ -181, -120, -91, 91, 120, 181 ],