Browse Source

consolidating suggest_poi and suggest_admin into one suggest endpoint. fixing tests (more tests to come)

pull/27/head
Harish Krishna 10 years ago
parent
commit
f1d13c1337
  1. 4
      app.js
  2. 120
      controller/suggest.js
  3. 50
      controller/suggest_admin.js
  4. 46
      controller/suggest_poi.js
  5. 0
      query/suggest.js
  6. 29
      query/suggest_admin.js
  7. 15
      test/unit/controller/suggest.js
  8. 10
      test/unit/mock/backend.js
  9. 2
      test/unit/query/suggest.js

4
app.js

@ -22,8 +22,6 @@ var controllers = {};
controllers.index = require('./controller/index');
controllers.doc = require('./controller/doc');
controllers.suggest = require('./controller/suggest');
controllers.suggest_poi = require('./controller/suggest_poi');
controllers.suggest_admin = require('./controller/suggest_admin');
controllers.search = require('./controller/search');
/** ----------------------- routes ----------------------- **/
@ -36,8 +34,6 @@ app.get( '/doc', sanitisers.doc.middleware, controllers.doc() );
// suggest API
app.get( '/suggest', sanitisers.suggest.middleware, controllers.suggest() );
app.get( '/suggest/poi', sanitisers.suggest.middleware, controllers.suggest_poi() );
app.get( '/suggest/admin', sanitisers.suggest.middleware, controllers.suggest_admin() );
// search API
app.get( '/search', sanitisers.search.middleware, controllers.search() );

120
controller/suggest.js

@ -4,17 +4,19 @@ var async = require('async');
function setup( backend, query ){
function controller( req, res, next ){
// allow overriding of dependencies
backend = backend || require('../src/backend');
query = query || require('../query/suggest');
// combine the 2 queries
function controller( req, res, next ){
// allow overriding of dependencies
backend = backend || require('../src/backend');
var query_admin = require('../query/suggest_admin');
var query_poi = require('../query/suggest_poi');
var cmd = {
index: 'pelias'
index: 'pelias',
body: query( req.clean )
};
var SIZE = req.clean.size || 10;
var query_backend = function(cmd, callback) {
// query backend
backend().client.suggest( cmd, function( err, data ){
@ -55,57 +57,67 @@ function setup( backend, query ){
return res.status(200).json( geojson );
};
var async_query;
if (req.clean.input.length < 4 && isNaN(parseInt(req.clean.input, 10))) {
async_query = {
a: function(callback){
cmd.body = query_admin( req.clean, 3 );
query_backend(cmd, callback);
},
b: function(callback){
cmd.body = query_admin( req.clean, 1 );
query_backend(cmd, callback);
},
c: function(callback) {
cmd.body = query_poi( req.clean, 3 );
query_backend(cmd, callback);
if (req.clean.input) {
var async_query;
// admin only
req.admin = {};
for (k in req.clean) { req.admin[k] = req.clean[k] }
req.admin.layers = ['admin0','admin1','admin2'];
if (req.clean.input.length < 4 && isNaN(parseInt(req.clean.input, 10))) {
async_query = {
a: function(callback){
cmd.body = query( req.admin, 3 );
query_backend(cmd, callback);
},
b: function(callback){
cmd.body = query( req.admin, 1 );
query_backend(cmd, callback);
},
c: function(callback) {
cmd.body = query( req.clean, 3 );
query_backend(cmd, callback);
}
}
}
} else {
async_query = {
a: function(callback){
cmd.body = query_poi( req.clean, 5);
query_backend(cmd, callback);
},
b: function(callback){
cmd.body = query_poi( req.clean, 3);
query_backend(cmd, callback);
},
c: function(callback){
cmd.body = query_poi( req.clean, 1 );
query_backend(cmd, callback);
},
d: function(callback){
cmd.body = query_admin( req.clean );
query_backend(cmd, callback);
} else {
async_query = {
a: function(callback){
cmd.body = query( req.clean, 5);
query_backend(cmd, callback);
},
b: function(callback){
cmd.body = query( req.clean, 3);
query_backend(cmd, callback);
},
c: function(callback){
cmd.body = query( req.clean, 1 );
query_backend(cmd, callback);
},
d: function(callback){
cmd.body = query( req.admin );
query_backend(cmd, callback);
}
}
}
}
async.parallel(async_query, function(err, results) {
var splice_length = parseInt((req.clean.size / Object.keys(results).length), 10);
// results is equal to: {a: docs, b: docs, c: docs}
var combined = [];
for (keys in results) {
combined = combined.concat(results[keys].splice(0,splice_length));
}
combined = dedup(combined);
respond(combined);
});
async.parallel(async_query, function(err, results) {
var splice_length = parseInt((SIZE / Object.keys(results).length), 10);
// results is equal to: {a: docs, b: docs, c: docs}
var combined = [];
for (keys in results) {
combined = combined.concat(results[keys].splice(0,splice_length));
}
combined = dedup(combined);
respond(combined);
});
} else {
query_backend(cmd, function(err, results) {
respond(results);
});
}
}
return controller;

50
controller/suggest_admin.js

@ -1,50 +0,0 @@
/**
README: http://www.elasticsearch.org/guide/en/elasticsearch/client/javascript-api/current/api-reference.html#api-suggest
**/
var geojsonify = require('../helper/geojsonify').suggest;
function setup( backend, query ){
// allow overriding of dependencies
backend = backend || require('../src/backend');
query = query || require('../query/suggest_admin');
function controller( req, res, next ){
// backend command
var cmd = {
index: 'pelias',
body: query( req.clean )
};
// query backend
backend().client.suggest( cmd, function( err, data ){
var docs = [];
// handle backend errors
if( err ){ return next( err ); }
// map response to a valid FeatureCollection
if( data && Array.isArray( data.pelias ) && data.pelias.length ){
docs = data['pelias'][0].options || [];
}
// convert docs to geojson
var geojson = geojsonify( docs );
// response envelope
geojson.date = new Date().getTime();
// respond
return res.status(200).json( geojson );
});
}
return controller;
}
module.exports = setup;

46
controller/suggest_poi.js

@ -1,46 +0,0 @@
var geojsonify = require('../helper/geojsonify').suggest;
function setup( backend, query ){
// allow overriding of dependencies
backend = backend || require('../src/backend');
query = query || require('../query/suggest_poi');
function controller( req, res, next ){
// backend command
var cmd = {
index: 'pelias',
body: query( req.clean )
};
// query backend
backend().client.suggest( cmd, function( err, data ){
var docs = [];
// handle backend errors
if( err ){ return next( err ); }
// map response to a valid FeatureCollection
if( data && Array.isArray( data.pelias ) && data.pelias.length ){
docs = data['pelias'][0].options || [];
}
// convert docs to geojson
var geojson = geojsonify( docs );
// response envelope
geojson.date = new Date().getTime();
// respond
return res.status(200).json( geojson );
});
}
return controller;
}
module.exports = setup;

0
query/suggest_poi.js → query/suggest.js

29
query/suggest_admin.js

@ -1,29 +0,0 @@
var logger = require('../src/logger');
// Build pelias suggest query
function generate( params, precision ){
var cmd = {
'pelias' : {
'text' : params.input,
'completion' : {
'size' : params.size,
'field' : 'suggest',
'context': {
'dataset': ['admin0','admin1','admin2'],
'location': {
'value': [ params.lon, params.lat ],
'precision': precision || 1
}
}
}
}
};
// logger.log( 'cmd', JSON.stringify( cmd, null, 2 ) );
return cmd;
}
module.exports = generate;

15
test/unit/controller/suggest.js

@ -1,5 +1,5 @@
var setup = require('../../../controller/suggest_poi'),
var setup = require('../../../controller/suggest'),
mockBackend = require('../mock/backend'),
mockQuery = require('../mock/query');
@ -24,7 +24,7 @@ module.exports.tests.functional_success = function(test, common) {
coordinates: [ 101, -10.1 ]
},
properties: {
id: 'mockid',
id: 'mockid1',
type: 'mocktype',
value: 1
}
@ -35,7 +35,7 @@ module.exports.tests.functional_success = function(test, common) {
coordinates: [ 101, -10.1 ]
},
properties: {
id: 'mockid',
id: 'mockid2',
type: 'mocktype',
value: 2
}
@ -43,7 +43,12 @@ module.exports.tests.functional_success = function(test, common) {
test('functional success', function(t) {
var backend = mockBackend( 'client/suggest/ok/1', function( cmd ){
t.deepEqual(cmd, { body: { a: 'b' }, index: 'pelias' }, 'correct backend command');
if (cmd.body.layers) {
// layers are set exclusively for admin: test for admin-only layers
t.deepEqual(cmd, { body: { input: 'b', layers: [ 'admin0', 'admin1', 'admin2' ] }, index: 'pelias' }, 'correct backend command');
} else {
t.deepEqual(cmd, { body: { input: 'b' }, index: 'pelias' }, 'correct backend command');
}
});
var controller = setup( backend, mockQuery() );
var res = {
@ -60,7 +65,7 @@ module.exports.tests.functional_success = function(test, common) {
t.end();
}
};
controller( { clean: { a: 'b' } }, res );
controller( { clean: { input: 'b' } }, res );
});
};

10
test/unit/mock/backend.js

@ -1,12 +1,14 @@
var mockPayload = {
id: 'mocktype/mockid',
geo: '101,-10.1'
var mockPayload = function(id){
return {
id: 'mocktype/mockid'+id,
geo: '101,-10.1'
}
};
var responses = {};
responses['client/suggest/ok/1'] = function( cmd, cb ){
return cb( undefined, suggestEnvelope([ { value: 1, payload: mockPayload }, { value: 2, payload: mockPayload } ]) );
return cb( undefined, suggestEnvelope([ { value: 1, payload: mockPayload(1) }, { value: 2, payload: mockPayload(2) } ]) );
};
responses['client/suggest/fail/1'] = function( cmd, cb ){
return cb( 'a backend error occurred' );

2
test/unit/query/suggest.js

@ -1,5 +1,5 @@
var generate = require('../../../query/suggest_poi');
var generate = require('../../../query/suggest');
module.exports.tests = {};

Loading…
Cancel
Save