diff --git a/layout/ComponentFallbackQuery.js b/layout/ComponentFallbackQuery.js index 9de1d8a..b376299 100644 --- a/layout/ComponentFallbackQuery.js +++ b/layout/ComponentFallbackQuery.js @@ -1,17 +1,9 @@ // This query is used for component geocodes, where the individual fields have -// been specified by the user and therefore doesn't need to be parsed. The main -// difference between this and FallbackQuery is that component geocoding contains -// the entire address in one field (`input:address`) whereas libpostal parses -// out the house number and street as separate field (`input:housenumber` and -// `input:street`). Because there is no reasonable way (at this time) to parse -// out house number and street from address, both the `address` and `street` -// layers must be queried for. It functions much like FallbackQuery but with a -// few notable exceptions: -// -// - `address` is searched for in `name.default` -// - `fallback.street` is scored much higher than `fallback.address` because -// otherwise `address` queries rank much higher +// been specified by the user and therefore doesn't need to be parsed. It functions +// much like FallbackQuery but with (currently) one notable exceptions: // +// - if locality is available but borough isn't, query borough layer with locality value +// - boosts are hardcoded var _ = require('lodash'); var baseQuery = require('./baseQuery'); @@ -192,30 +184,26 @@ function addQuery(vs) { } -function addAddress(vs) { +function addHouseNumberAndStreet(vs) { var o = { bool: { _name: 'fallback.address', - must: [], + must: [ + { + match_phrase: { + 'address_parts.number': vs.var('input:housenumber').toString() + } + }, + { + match_phrase: { + 'address_parts.street': vs.var('input:street').toString() + } + } + ], should: [], filter: { - bool: { - must: [ - { - term: { - layer: 'address' - } - }, - { - query_string: { - default_field: 'name.default', - default_operator: 'AND', - analyzer: 'peliasQueryFullToken', - query: vs.var('input:address').toString() - } - } - ] - + term: { + layer: 'address' } } } @@ -244,7 +232,7 @@ function addStreet(vs) { must: [ { match_phrase: { - 'address_parts.street': vs.var('input:address').toString() + 'address_parts.street': vs.var('input:street').toString() } } ], @@ -455,8 +443,10 @@ Layout.prototype.render = function( vs ){ var funcScoreShould = q.query.function_score.query.filtered.query.bool.should; - if (vs.isset('input:address')) { - funcScoreShould.push(addAddress(vs)); + if (vs.isset('input:housenumber') && vs.isset('input:street')) { + funcScoreShould.push(addHouseNumberAndStreet(vs)); + } + if (vs.isset('input:street')) { funcScoreShould.push(addStreet(vs)); } if (vs.isset('input:neighbourhood')) { diff --git a/test/fixtures/componentFallbackQuery/address.json b/test/fixtures/componentFallbackQuery/address.json index f071379..64611fc 100644 --- a/test/fixtures/componentFallbackQuery/address.json +++ b/test/fixtures/componentFallbackQuery/address.json @@ -10,6 +10,16 @@ "bool": { "_name": "fallback.address", "must": [ + { + "match_phrase": { + "address_parts.number": "house number value" + } + }, + { + "match_phrase": { + "address_parts.street": "street value" + } + }, { "multi_match": { "query": "neighbourhood value", @@ -81,22 +91,8 @@ ], "should": [], "filter": { - "bool": { - "must": [ - { - "term": { - "layer": "address" - } - }, - { - "query_string": { - "default_field": "name.default", - "default_operator": "AND", - "analyzer": "peliasQueryFullToken", - "query": "address value" - } - } - ] + "term": { + "layer": "address" } }, "boost": 50 @@ -108,7 +104,7 @@ "must": [ { "match_phrase": { - "address_parts.street": "address value" + "address_parts.street": "street value" } }, { diff --git a/test/fixtures/componentFallbackQuery/address_with_postcode.json b/test/fixtures/componentFallbackQuery/address_with_postcode.json index 793a29d..ed3e961 100644 --- a/test/fixtures/componentFallbackQuery/address_with_postcode.json +++ b/test/fixtures/componentFallbackQuery/address_with_postcode.json @@ -9,7 +9,18 @@ { "bool": { "_name": "fallback.address", - "must": [], + "must": [ + { + "match_phrase": { + "address_parts.number": "house number value" + } + }, + { + "match_phrase": { + "address_parts.street": "street value" + } + } + ], "should": [ { "match_phrase": { @@ -18,22 +29,8 @@ } ], "filter": { - "bool": { - "must": [ - { - "term": { - "layer": "address" - } - }, - { - "query_string": { - "default_field": "name.default", - "default_operator": "AND", - "analyzer": "peliasQueryFullToken", - "query": "address value" - } - } - ] + "term": { + "layer": "address" } }, "boost": 50 @@ -45,7 +42,7 @@ "must": [ { "match_phrase": { - "address_parts.street": "address value" + "address_parts.street": "street value" } } ], diff --git a/test/layout/ComponentFallbackQuery.js b/test/layout/ComponentFallbackQuery.js index f3aa938..d6ee512 100644 --- a/test/layout/ComponentFallbackQuery.js +++ b/test/layout/ComponentFallbackQuery.js @@ -42,7 +42,8 @@ module.exports.tests.base_render = function(test, common) { var vs = new VariableStore(); vs.var('size', 'size value'); vs.var('track_scores', 'track_scores value'); - vs.var('input:address', 'address value'); + vs.var('input:housenumber', 'house number value'); + vs.var('input:street', 'street value'); vs.var('input:neighbourhood', 'neighbourhood value'); vs.var('input:borough', 'borough value'); vs.var('input:locality', 'locality value'); @@ -64,7 +65,8 @@ module.exports.tests.base_render = function(test, common) { var vs = new VariableStore(); vs.var('size', 'size value'); vs.var('track_scores', 'track_scores value'); - vs.var('input:address', 'address value'); + vs.var('input:housenumber', 'house number value'); + vs.var('input:street', 'street value'); vs.var('input:postcode', 'postcode value'); var fs = require('fs');