Browse Source

refactor reverse & tests

pull/229/head
Peter Johnson 9 years ago
parent
commit
1f13bafab0
  1. 59
      query/reverse.js
  2. 12
      query/search.js
  3. 43
      test/unit/fixture/reverse_standard.js
  4. 189
      test/unit/query/reverse.js

59
query/reverse.js

@ -1,33 +1,52 @@
var queries = require('geopipes-elasticsearch-backend').queries, var peliasQuery = require('pelias-query'),
sort = require('./sort'); sort = require('./sort');
function generate( params ){ //------------------------------
// reverse geocode query
//------------------------------
var query = new peliasQuery.layout.FilteredBooleanQuery();
var centroid = { // scoring boost
lat: params.lat, query.sort( peliasQuery.view.sort_distance );
lon: params.lon
};
var query = queries.distance( centroid, { // non-scoring hard filters
size: params.size || 1, query.filter( peliasQuery.view.boundary_circle );
sort: true,
distance: '500km' // --------------------------------
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 ) { // focus point centroid
addCategoriesFilter( query, params.categories ); 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 ) { // @todo: remove this hack
query.query.filtered.filter.bool.must.push({ return JSON.parse( JSON.stringify( result ) );
terms: { category: categories }
});
} }
module.exports = generate; module.exports = generateQuery;

12
query/search.js

@ -32,12 +32,12 @@ query.score( peliasQuery.view.admin('locality') );
query.score( peliasQuery.view.admin('neighborhood') ); query.score( peliasQuery.view.admin('neighborhood') );
// non-scoring hard filters // non-scoring hard filters
query.filter( peliasQuery.view.boundary_circle, 'must' ); query.filter( peliasQuery.view.boundary_circle );
query.filter( peliasQuery.view.boundary_rect, 'must' ); query.filter( peliasQuery.view.boundary_rect );
// -------------------------------- // --------------------------------
function generate( clean ){ function generateQuery( clean ){
var vs = new peliasQuery.Vars( peliasQuery.defaults ); var vs = new peliasQuery.Vars( peliasQuery.defaults );
@ -125,7 +125,7 @@ function generate( clean ){
// ==== deal with the 'leftover' components ==== // ==== deal with the 'leftover' components ====
// @todo: clean up this code // @todo: clean up this code
// a concept called 'leftovers' which is just 'admin_parts' plus 'regions'. // a concept called 'leftovers' which is just 'admin_parts' /or 'regions'.
var leftoversString = ''; var leftoversString = '';
if( clean.parsed_input.hasOwnProperty('admin_parts') ){ if( clean.parsed_input.hasOwnProperty('admin_parts') ){
leftoversString = clean.parsed_input.admin_parts; leftoversString = clean.parsed_input.admin_parts;
@ -150,10 +150,12 @@ function generate( clean ){
} }
var result = query.render( vs ); var result = query.render( vs );
// @todo: remove unnessesary sort conditions
result.sort = result.sort.concat( sort( clean ) ); result.sort = result.sort.concat( sort( clean ) );
// @todo: remove this hack // @todo: remove this hack
return JSON.parse( JSON.stringify( result ) ); return JSON.parse( JSON.stringify( result ) );
} }
module.exports = generate; module.exports = generateQuery;

43
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
};

189
test/unit/query/reverse.js

@ -1,15 +1,16 @@
var generate = require('../../../query/reverse'); 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 = {}; 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) { module.exports.tests.interface = function(test, common) {
test('valid interface', function(t) { test('valid interface', function(t) {
t.equal(typeof generate, 'function', 'valid function'); 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) { module.exports.tests.query = function(test, common) {
test('valid query', function(t) { test('valid query', function(t) {
var query = generate({ var query = generate({
lat: 29.49136, lon: -82.50622 lat: 29.49136, lon: -82.50622
}); });
var expected = { var expected = require('../fixture/reverse_standard');
'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
};
t.deepEqual(query, expected, 'valid reverse query'); t.deepEqual(query, expected, 'valid reverse query');
t.end();
});
test('size fuzz test', function(t) {
// test different sizes // test different sizes
var sizes = [1,2,10,undefined,null]; var sizes = [1,2,10,undefined,null];
sizes.forEach( function(size) { sizes.forEach( function( size ){
query = generate({ var query = generate({
lat: 29.49136, lon: -82.50622, size: size 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'); t.equal( query.size, size ? size : 1, 'valid reverse query for size: '+ size);
// 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(); t.end();
}); });

Loading…
Cancel
Save