Browse Source

Add categories param to /reverse

pull/115/head
Diana Shkolnikov 10 years ago
parent
commit
1bf0fcd298
  1. 21
      query/reverse.js
  2. 38
      sanitiser/_categories.js
  3. 7
      sanitiser/reverse.js
  4. 66
      test/unit/query/reverse.js
  5. 42
      test/unit/sanitiser/reverse.js

21
query/reverse.js

@ -1,7 +1,6 @@
var logger = require('../src/logger'), var queries = require('geopipes-elasticsearch-backend').queries,
queries = require('geopipes-elasticsearch-backend').queries, sort = require('./sort');
sort = require('../query/sort');
function generate( params ){ function generate( params ){
@ -13,7 +12,23 @@ function generate( params ){
var query = queries.distance( centroid, { size: params.size || 1 } ); var query = queries.distance( centroid, { size: params.size || 1 } );
query.sort = query.sort.concat(sort); query.sort = query.sort.concat(sort);
if ( params.categories && params.categories.length > 0 ) {
addCategoriesFilter( query, params.categories );
}
return query; return query;
} }
function addCategoriesFilter( query, categories ) {
query.query.filtered.query = {
match: {
category: {
query: categories.join(' '),
analyzer: 'standard',
operator: 'or'
}
}
};
}
module.exports = generate; module.exports = generate;

38
sanitiser/_categories.js

@ -0,0 +1,38 @@
var isObject = require('is-object');
// validate inputs, convert types and apply defaults
function sanitize( req ){
var clean = req.clean || {};
var params= req.query;
// ensure the input params are a valid object
if( !isObject( params ) ){
params = {};
}
// default case (no categories specified in GET params)
if('string' !== typeof params.categories || !params.categories.length){
clean.categories = [];
}
else {
// parse GET params
clean.categories = params.categories.split(',')
.map(function (cat) {
return cat.toLowerCase().trim(); // lowercase inputs
})
.filter( function( cat ) {
return ( cat.length > 0 );
});
}
// pass validated params to next middleware
req.clean = clean;
return { 'error': false };
}
// export function
module.exports = sanitize;

7
sanitiser/reverse.js

@ -1,6 +1,5 @@
var logger = require('../src/logger'), var _sanitize = require('../sanitiser/_sanitize'),
_sanitize = require('../sanitiser/_sanitize'),
sanitiser = { sanitiser = {
latlonzoom: function( req ) { latlonzoom: function( req ) {
var geo = require('../sanitiser/_geo'); var geo = require('../sanitiser/_geo');
@ -10,6 +9,10 @@ var logger = require('../src/logger'),
size: function( req ) { size: function( req ) {
var size = require('../sanitiser/_size'); var size = require('../sanitiser/_size');
return size(req, 1); return size(req, 1);
},
categories: function ( req ) {
var categories = require('../sanitiser/_categories');
return categories(req);
} }
}; };

66
test/unit/query/reverse.js

@ -111,6 +111,72 @@ module.exports.tests.query = function(test, common) {
}); });
t.end(); 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': {
'category': {
'query': 'food education entertainment',
'analyzer': 'standard',
'operator': 'or'
}
}
},
'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',
{
'_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.end();
});
}; };
module.exports.all = function (tape, common) { module.exports.all = function (tape, common) {

42
test/unit/sanitiser/reverse.js

@ -8,7 +8,8 @@ var suggest = require('../../../sanitiser/reverse'),
layers: [ 'geoname', 'osmnode', 'osmway', 'admin0', 'admin1', 'admin2', 'neighborhood', layers: [ 'geoname', 'osmnode', 'osmway', 'admin0', 'admin1', 'admin2', 'neighborhood',
'locality', 'local_admin', 'osmaddress', 'openaddresses' ], 'locality', 'local_admin', 'osmaddress', 'openaddresses' ],
lon: 0, lon: 0,
size: 1 size: 1,
categories: []
}, },
sanitize = function(query, cb) { _sanitize({'query':query}, cb); }; sanitize = function(query, cb) { _sanitize({'query':query}, cb); };
@ -200,6 +201,45 @@ module.exports.tests.sanitize_layers = function(test, common) {
}); });
}; };
module.exports.tests.sanitize_categories = function(test, common) {
var queryParams = { input: 'test', lat: 0, lon: 0 };
test('unspecified', function(t) {
queryParams.categories = undefined;
sanitize(queryParams, function( err, clean ){
t.deepEqual(clean.categories, defaultClean.categories, 'default to empty categories array');
t.end();
});
});
test('single category', function(t) {
queryParams.categories = 'food';
sanitize(queryParams, function( err, clean ){
t.deepEqual(clean.categories, ['food'], 'category set');
t.end();
});
});
test('multiple categories', function(t) {
queryParams.categories = 'food,education,nightlife';
sanitize(queryParams, function( err, clean ){
t.deepEqual(clean.categories, ['food', 'education', 'nightlife'], 'categories set');
t.end();
});
});
test('whitespace and empty strings', function(t) {
queryParams.categories = 'food, , nightlife ,';
sanitize(queryParams, function( err, clean ){
t.deepEqual(clean.categories, ['food', 'nightlife'], 'categories set');
t.end();
});
});
test('all empty strings', function(t) {
queryParams.categories = ', , ,';
sanitize(queryParams, function( err, clean ){
t.deepEqual(clean.categories, defaultClean.categories, 'empty strings filtered out');
t.end();
});
});
};
module.exports.tests.middleware_failure = function(test, common) { module.exports.tests.middleware_failure = function(test, common) {
test('middleware failure', function(t) { test('middleware failure', function(t) {
var res = { status: function( code ){ var res = { status: function( code ){

Loading…
Cancel
Save