Browse Source

using multiple suggesters but one query

pull/59/head
Harish Krishna 10 years ago
parent
commit
2b2414d879
  1. 10
      controller/suggest_nearby.js
  2. 48
      helper/results.js
  3. 97
      query/suggest_multiple.js
  4. 44
      service/suggest_multiple.js

10
controller/suggest_nearby.js

@ -1,15 +1,16 @@
var service = {
suggest: require('../service/suggest'),
suggest: require('../service/suggest_multiple'),
mget: require('../service/mget')
};
var geojsonify = require('../helper/geojsonify').search;
var resultsHelper = require('../helper/results');
function setup( backend, query ){
// allow overriding of dependencies
backend = backend || require('../src/backend');
query = query || require('../query/suggest');
query = query || require('../query/suggest_multiple');
function controller( req, res, next ){
@ -37,7 +38,10 @@ function setup( backend, query ){
// error handler
if( err ){ return next( err ); }
// pick the required number of results
suggested = resultsHelper.picker(suggested, req.clean.size);
// no documents suggested, return empty array to avoid ActionRequestValidationException
if( !Array.isArray( suggested ) || !suggested.length ){
return reply([]);

48
helper/results.js

@ -0,0 +1,48 @@
var picker = function( results, size ){
var combined = [];
var num_results = 0;
for (var i=0; i<results.length && num_results<size; i++) {
if (results[i] && results[i].length) {
combined[i] = combined[i] || [];
combined[i].push(results[i][0]);
results[i].splice(0,1);
num_results++;
} else {
results.splice(i,1);
i--;
}
if (i === results.length-1) {
i=0;
}
}
return (combined.length > 0) ? sort_by_score(combined) : combined;
};
var dedup = function(arr) {
var unique_ids = [];
return arr.filter(function(item, pos) {
if (unique_ids.indexOf(item.name.default) === -1) {
unique_ids.push(item.name.default);
return true;
}
return false;
});
};
var sort_by_score = function(arr) {
return arr.map(function(doc) {
return doc.sort(function(a,b) {
return b.score - a.score;
});
}).reduce(function(a,b) { //flatten
return a.concat(b);
});
};
module.exports = {
picker: picker,
dedup: dedup
};

97
query/suggest_multiple.js

@ -0,0 +1,97 @@
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 = {
'text' : params.input,
'pelias_1' : {
'completion' : {
'size' : params.size,
'field' : 'suggest',
'context': {
'dataset': params.layers,
'location': {
'value': [ params.lon, params.lat ],
'precision': 5
}
}
}
},
'pelias_2' : {
'completion' : {
'size' : params.size,
'field' : 'suggest',
'context': {
'dataset': params.layers,
'location': {
'value': [ params.lon, params.lat ],
'precision': 3
}
}
}
},
'pelias_3' : {
'completion' : {
'size' : params.size,
'field' : 'suggest',
'context': {
'dataset': params.layers,
'location': {
'value': [ params.lon, params.lat ],
'precision': 1
}
}
}
},
'pelias_4' : {
'completion' : {
'size' : params.size,
'field' : 'suggest',
'context': {
'dataset': ['admin0', 'admin1', 'admin2'],
'location': {
'value': [ params.lon, params.lat ],
'precision': precision || getPrecision(params.zoom)
}
}
}
},
'pelias_5' : {
'completion' : {
'size' : params.size,
'field' : 'suggest',
'context': {
'dataset': params.layers,
'location': {
'value': [ params.lon, params.lat ],
'precision': 3
}
},
'fuzzy': {}
}
}
};
// logger.log( 'cmd', JSON.stringify( cmd, null, 2 ) );
return cmd;
}
module.exports = generate;

44
service/suggest_multiple.js

@ -0,0 +1,44 @@
/**
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 = [];
var unique_ids = [];
var num_keys = Object.keys(data).length;
var has_docs = function(obj) {
return Array.isArray( obj ) && obj.length && obj[0].options && obj[0].options.length;
};
for (var i=1, j=0; i<num_keys && j<num_keys; i++) {
var keys = 'pelias_'+i;
if ( has_docs(data[keys]) ){
docs[i] = docs[i] || [];
var res = data[keys][0].options[0];
if (unique_ids.indexOf(res.text) === -1) {
docs[i].push(res);
unique_ids.push(res.text);
}
data[keys][0].options.splice(0,1);
} else {
j++;
}
i = i === num_keys-1 ? 1 : i;
}
// fire callback
return cb( null, docs);
});
}
module.exports = service;
Loading…
Cancel
Save