var peliasQuery = require('pelias-query'), defaults = require('./autocomplete_defaults'), textParser = require('./text_parser'), check = require('check-types'); // additional views (these may be merged in to pelias/query at a later date) var views = { ngrams_strict: require('./view/ngrams_strict'), focus_selected_layers: require('./view/focus_selected_layers'), ngrams_last_token_only: require('./view/ngrams_last_token_only'), phrase_first_tokens_only: require('./view/phrase_first_tokens_only'), pop_subquery: require('./view/pop_subquery'), boost_exact_matches: require('./view/boost_exact_matches') }; //------------------------------ // autocomplete query //------------------------------ var query = new peliasQuery.layout.FilteredBooleanQuery(); // mandatory matches query.score( views.phrase_first_tokens_only, 'must' ); query.score( views.ngrams_last_token_only, 'must' ); // address components query.score( peliasQuery.view.address('housenumber') ); query.score( peliasQuery.view.address('street') ); query.score( peliasQuery.view.address('postcode') ); // admin components query.score( peliasQuery.view.admin('country') ); query.score( peliasQuery.view.admin('country_a') ); query.score( peliasQuery.view.admin('region') ); query.score( peliasQuery.view.admin('region_a') ); query.score( peliasQuery.view.admin('county') ); query.score( peliasQuery.view.admin('borough') ); query.score( peliasQuery.view.admin('localadmin') ); query.score( peliasQuery.view.admin('locality') ); query.score( peliasQuery.view.admin('neighbourhood') ); // scoring boost query.score( views.boost_exact_matches ); query.score( views.focus_selected_layers( views.ngrams_strict ) ); query.score( peliasQuery.view.popularity( views.pop_subquery ) ); query.score( peliasQuery.view.population( views.pop_subquery ) ); // non-scoring hard filters query.filter( peliasQuery.view.sources ); // -------------------------------- /** map request variables to query variables for all inputs provided by this HTTP request. **/ function generateQuery( clean ){ var vs = new peliasQuery.Vars( defaults ); // sources if( check.array(clean.sources) && clean.sources.length ){ vs.var( 'sources', clean.sources ); } // pass the input tokens to the views so they can choose which tokens // are relevant for their specific function. if( check.array( clean.tokens ) ){ vs.var( 'input:name:tokens', clean.tokens ); vs.var( 'input:name:tokens_complete', clean.tokens_complete ); vs.var( 'input:name:tokens_incomplete', clean.tokens_incomplete ); } // input text vs.var( 'input:name', clean.text ); // if the input parser has run and suggested a 'parsed_text.name' to use. if( clean.hasOwnProperty('parsed_text') && clean.parsed_text.hasOwnProperty('name') ){ // use 'parsed_text.name' instead of 'clean.text'. vs.var( 'input:name', clean.parsed_text.name ); } // focus point if( check.number(clean['focus.point.lat']) && check.number(clean['focus.point.lon']) ){ vs.set({ 'focus:point:lat': clean['focus.point.lat'], 'focus:point:lon': clean['focus.point.lon'] }); } // run the address parser if( clean.parsed_text ){ textParser( clean.parsed_text, vs ); } return query.render( vs ); } module.exports = generateQuery;