Browse Source

support new querying model

add support for FallbackQuery and GeodisambiguationQuery from the pelias-query module.  GeodisambiguationQuery is used when the text-analyzer returns a single administrative area field.  FallbackQuery is used otherwise.
pull/666/head
Stephen Hess 9 years ago
parent
commit
0aebf81ace
  1. 73
      query/search.js

73
query/search.js

@ -3,49 +3,47 @@ var peliasQuery = require('pelias-query'),
textParser = require('./text_parser'),
check = require('check-types');
var placeTypes = require('../helper/placeTypes');
// region_a is also an admin field. addressit tries to detect
// region_a, in which case we use a match query specifically for it.
// but address it doesn't know about all of them so it helps to search
// against this with the other admin parts as a fallback
var adminFields = placeTypes.concat(['region_a']);
//------------------------------
// general-purpose search query
//------------------------------
var query = new peliasQuery.layout.FilteredBooleanQuery();
var fallbackQuery = new peliasQuery.layout.FallbackQuery();
fallbackQuery.score( peliasQuery.view.popularity( peliasQuery.view.phrase ) );
fallbackQuery.score( peliasQuery.view.population( peliasQuery.view.phrase ) );
var geodisambiguationQuery = new peliasQuery.layout.GeodisambiguationQuery();
geodisambiguationQuery.score( peliasQuery.view.popularity( peliasQuery.view.phrase ) );
geodisambiguationQuery.score( peliasQuery.view.population( peliasQuery.view.phrase ) );
// mandatory matches
query.score( peliasQuery.view.boundary_country, 'must' );
query.score( peliasQuery.view.ngrams, 'must' );
// query.score( peliasQuery.view.boundary_country, 'must' );
// query.score( peliasQuery.view.ngrams, 'must' );
// scoring boost
query.score( peliasQuery.view.phrase );
query.score( peliasQuery.view.focus( peliasQuery.view.phrase ) );
query.score( peliasQuery.view.popularity( peliasQuery.view.phrase ) );
query.score( peliasQuery.view.population( peliasQuery.view.phrase ) );
// query.score( peliasQuery.view.phrase );
// query.score( peliasQuery.view.focus( peliasQuery.view.phrase ) );
// query.score( peliasQuery.view.popularity( peliasQuery.view.phrase ) );
// query.score( peliasQuery.view.population( peliasQuery.view.phrase ) );
// address components
query.score( peliasQuery.view.address('housenumber') );
query.score( peliasQuery.view.address('street') );
query.score( peliasQuery.view.address('postcode') );
// query.score( peliasQuery.view.address('housenumber'), 'must' );
// query.score( peliasQuery.view.address('street'), 'must' );
// query.score( peliasQuery.view.address('postcode'), 'must' );
// admin components
// country_a and region_a are left as matches here because the text-analyzer
// can sometimes detect them, in which case a query more specific than a
// multi_match is appropriate.
query.score( peliasQuery.view.admin('country_a') );
query.score( peliasQuery.view.admin('region_a') );
query.score( peliasQuery.view.admin_multi_match(adminFields, 'peliasAdmin') );
// query.score( peliasQuery.view.admin('country_a'), 'must' );
// query.score( peliasQuery.view.admin('region_a'), 'must' );
// query.score( peliasQuery.view.admin('locality'), 'must' );
// query.score( peliasQuery.view.admin_multi_match(adminFields, 'peliasAdmin') );
// non-scoring hard filters
query.filter( peliasQuery.view.boundary_circle );
query.filter( peliasQuery.view.boundary_rect );
query.filter( peliasQuery.view.sources );
query.filter( peliasQuery.view.layers );
query.filter( peliasQuery.view.categories );
// query.filter( peliasQuery.view.boundary_circle );
// query.filter( peliasQuery.view.boundary_rect );
// query.filter( peliasQuery.view.sources );
// query.filter( peliasQuery.view.layers );
// query.filter( peliasQuery.view.categories );
// --------------------------------
/**
@ -131,4 +129,25 @@ function generateQuery( clean ){
return q;
}
function getQuery(vs) {
if (isSingleFieldGeoambiguity(vs) && !hasQueryOrAddress(vs)) {
return geodisambiguationQuery.render(vs);
} else {
return fallbackQuery.render(vs);
}
}
function isSingleFieldGeoambiguity(vs) {
return ['neighbourhood', 'borough', 'locality', 'county', 'region', 'country'].filter(function(layer) {
return vs.isset('input:' + layer);
}).length === 1;
}
function hasQueryOrAddress(vs) {
return ['housenumber', 'street', 'query', 'category'].filter(function(layer) {
return vs.isset('input:' + layer);
}).length > 0;
}
module.exports = generateQuery;

Loading…
Cancel
Save