mirror of https://github.com/pelias/api.git
Harish Krishna
10 years ago
4 changed files with 227 additions and 0 deletions
@ -0,0 +1,153 @@ |
|||||||
|
|
||||||
|
var service = { |
||||||
|
suggest: require('../service/suggest_old'), |
||||||
|
mget: require('../service/mget') |
||||||
|
}; |
||||||
|
var geojsonify = require('../helper/geojsonify').search; |
||||||
|
var async = require('async'); |
||||||
|
|
||||||
|
function setup( backend, query ){ |
||||||
|
|
||||||
|
// allow overriding of dependencies
|
||||||
|
backend = backend || require('../src/backend'); |
||||||
|
query = query || require('../query/suggest_old'); |
||||||
|
|
||||||
|
function controller( req, res, next ){ |
||||||
|
|
||||||
|
var cmd = { |
||||||
|
index: 'pelias', |
||||||
|
body: query( req.clean ) |
||||||
|
}; |
||||||
|
|
||||||
|
var SIZE = req.clean.size || 10; |
||||||
|
|
||||||
|
var query_backend = function(cmd, callback) { |
||||||
|
// query backend
|
||||||
|
service.suggest( backend, cmd, function( err, docs ){ |
||||||
|
|
||||||
|
// error handler
|
||||||
|
if( err ){ return next( err ); } |
||||||
|
callback(null, docs); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
var dedup = function(combined) { |
||||||
|
var unique_ids = []; |
||||||
|
return combined.filter(function(item, pos) { |
||||||
|
if (unique_ids.indexOf(item.text) === -1) { |
||||||
|
unique_ids.push(item.text); |
||||||
|
return true; |
||||||
|
} |
||||||
|
return false; |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
var reply = function(docs) { |
||||||
|
|
||||||
|
// convert docs to geojson
|
||||||
|
var geojson = geojsonify( docs ); |
||||||
|
|
||||||
|
// response envelope
|
||||||
|
geojson.date = new Date().getTime(); |
||||||
|
|
||||||
|
// respond
|
||||||
|
return res.status(200).json( geojson ); |
||||||
|
}; |
||||||
|
|
||||||
|
var respond = function(data) { |
||||||
|
|
||||||
|
// no documents suggested, return empty array to avoid ActionRequestValidationException
|
||||||
|
if( !Array.isArray( data ) || !data.length ){ |
||||||
|
return reply([]); |
||||||
|
} |
||||||
|
|
||||||
|
// map suggester output to mget query
|
||||||
|
var query = data.map( function( doc ) { |
||||||
|
var idParts = doc.text.split(':'); |
||||||
|
return { |
||||||
|
_index: 'pelias', |
||||||
|
_type: idParts[0], |
||||||
|
_id: idParts.slice(1).join(':') |
||||||
|
}; |
||||||
|
}); |
||||||
|
|
||||||
|
service.mget( backend, query, function( err, docs ){ |
||||||
|
|
||||||
|
// error handler
|
||||||
|
if( err ){ return next( err ); } |
||||||
|
|
||||||
|
// reply
|
||||||
|
return reply( docs ); |
||||||
|
|
||||||
|
}); |
||||||
|
|
||||||
|
}; |
||||||
|
|
||||||
|
if (req.clean.input) { |
||||||
|
var async_query; |
||||||
|
|
||||||
|
// admin only
|
||||||
|
req.admin = {}; |
||||||
|
for (var 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 = { |
||||||
|
admin_3p: function(callback){ |
||||||
|
cmd.body = query( req.admin, 3 ); |
||||||
|
query_backend(cmd, callback); |
||||||
|
}, |
||||||
|
admin_1p: function(callback){ |
||||||
|
cmd.body = query( req.admin, 1 ); |
||||||
|
query_backend(cmd, callback); |
||||||
|
}, |
||||||
|
all_3p: function(callback) { |
||||||
|
cmd.body = query( req.clean, 3 ); |
||||||
|
query_backend(cmd, callback); |
||||||
|
} |
||||||
|
}; |
||||||
|
} else { |
||||||
|
async_query = { |
||||||
|
all_5p: function(callback){ |
||||||
|
cmd.body = query( req.clean, 5); |
||||||
|
query_backend(cmd, callback); |
||||||
|
}, |
||||||
|
all_3p: function(callback){ |
||||||
|
cmd.body = query( req.clean, 3); |
||||||
|
query_backend(cmd, callback); |
||||||
|
}, |
||||||
|
all_1p: function(callback){ |
||||||
|
cmd.body = query( req.clean, 1 ); |
||||||
|
query_backend(cmd, callback); |
||||||
|
}, |
||||||
|
admin_1p: function(callback){ |
||||||
|
cmd.body = query( req.admin ); |
||||||
|
query_backend(cmd, callback); |
||||||
|
} |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
async.parallel(async_query, function(err, results) { |
||||||
|
// results is equal to: {a: docs, b: docs, c: docs}
|
||||||
|
var splice_length = parseInt((SIZE / Object.keys(results).length), 10); |
||||||
|
var results_keys = Object.keys(async_query); |
||||||
|
|
||||||
|
var combined = []; |
||||||
|
results_keys.forEach(function(key){ |
||||||
|
combined = combined.concat(results[key].splice(0,splice_length)); |
||||||
|
}); |
||||||
|
combined = dedup(combined); |
||||||
|
respond(combined); |
||||||
|
}); |
||||||
|
} else { |
||||||
|
query_backend(cmd, function(err, results) { |
||||||
|
respond(results); |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
return controller; |
||||||
|
} |
||||||
|
|
||||||
|
module.exports = setup; |
@ -0,0 +1,44 @@ |
|||||||
|
|
||||||
|
var logger = require('../src/logger'); |
||||||
|
|
||||||
|
// Build pelias suggest query
|
||||||
|
function generate( params, precision ){ |
||||||
|
|
||||||
|
var getPrecision = function(zoom) { |
||||||
|
switch (true) { |
||||||
|
case (zoom > 15): |
||||||
|
return 5; // zoom: >= 16
|
||||||
|
case (zoom > 9): |
||||||
|
return 4; // zoom: 10-15
|
||||||
|
case (zoom > 5): |
||||||
|
return 3; // zoom: 6-9
|
||||||
|
case (zoom > 3): |
||||||
|
return 2; // zoom: 4-5
|
||||||
|
default: |
||||||
|
return 1; // zoom: 1-3 or when zoom: undefined
|
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
var cmd = { |
||||||
|
'pelias' : { |
||||||
|
'text' : params.input, |
||||||
|
'completion' : { |
||||||
|
'size' : params.size, |
||||||
|
'field' : 'suggest', |
||||||
|
'context': { |
||||||
|
'dataset': params.layers, |
||||||
|
'location': { |
||||||
|
'value': [ params.lon, params.lat ], |
||||||
|
'precision': precision || getPrecision(params.zoom) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
// logger.log( 'cmd', JSON.stringify( cmd, null, 2 ) );
|
||||||
|
return cmd; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
module.exports = generate; |
@ -0,0 +1,28 @@ |
|||||||
|
|
||||||
|
/** |
||||||
|
|
||||||
|
cmd can be any valid ES suggest command |
||||||
|
|
||||||
|
**/ |
||||||
|
|
||||||
|
function service( backend, cmd, cb ){ |
||||||
|
|
||||||
|
// query new backend
|
||||||
|
backend().client.suggest( cmd, function( err, data ){ |
||||||
|
|
||||||
|
// handle backend errors
|
||||||
|
if( err ){ return cb( err ); } |
||||||
|
|
||||||
|
// map returned documents
|
||||||
|
var docs = []; |
||||||
|
if( data && Array.isArray( data.pelias ) && data.pelias.length ){ |
||||||
|
docs = data.pelias[0].options || []; |
||||||
|
} |
||||||
|
|
||||||
|
// fire callback
|
||||||
|
return cb( null, docs ); |
||||||
|
}); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
module.exports = service; |
Loading…
Reference in new issue