From d74b89301073c1128b9ac601fbbe05ee1315950d Mon Sep 17 00:00:00 2001 From: missinglink Date: Fri, 8 Nov 2019 11:19:56 +0100 Subject: [PATCH] feat(search): use libpostal parses for venue queries where available --- query/search.js | 6 +- .../search_fallback_venue_city_country.js | 196 ++++++++++++++++++ .../search_fallback_venue_city_state.js | 196 ++++++++++++++++++ test/unit/query/search.js | 14 +- 4 files changed, 409 insertions(+), 3 deletions(-) create mode 100644 test/unit/fixture/search_fallback_venue_city_country.js create mode 100644 test/unit/fixture/search_fallback_venue_city_state.js diff --git a/query/search.js b/query/search.js index 9333a25f6..8920f1a15 100644 --- a/query/search.js +++ b/query/search.js @@ -121,7 +121,7 @@ function generateQuery( clean ){ } function getQuery(vs) { - if (hasStreet(vs) || isPostalCodeOnly(vs) || isPostalCodeWithAdmin(vs)) { + if (hasStreet(vs) || isPostalCodeOnly(vs) || isPostalCodeWithAdmin(vs) || isVenue(vs)) { return { type: 'search_fallback', body: fallbackQuery.render(vs) @@ -156,6 +156,10 @@ function hasStreet(vs) { return vs.isset('input:street'); } +function isVenue(vs) { + return determineQueryType(vs) === 'venue'; +} + function isPostalCodeOnly(vs) { var isSet = layer => vs.isset(`input:${layer}`); diff --git a/test/unit/fixture/search_fallback_venue_city_country.js b/test/unit/fixture/search_fallback_venue_city_country.js new file mode 100644 index 000000000..571426b8c --- /dev/null +++ b/test/unit/fixture/search_fallback_venue_city_country.js @@ -0,0 +1,196 @@ +module.exports = { + 'query': { + 'function_score': { + 'query': { + 'bool': { + 'minimum_should_match': 1, + 'should': [ + { + 'bool': { + '_name': 'fallback.venue', + 'must': [ + { + 'multi_match': { + 'query': 'query value', + 'type': 'phrase', + 'fields': [ + 'phrase.default' + ] + } + }, + { + 'multi_match': { + 'query': 'city value', + 'type': 'phrase', + 'fields': [ + 'parent.locality', + 'parent.locality_a', + 'parent.localadmin', + 'parent.localadmin_a' + ] + } + }, + { + 'multi_match': { + 'query': 'country value', + 'type': 'phrase', + 'fields': [ + 'parent.country', + 'parent.country_a', + 'parent.dependency', + 'parent.dependency_a' + ] + } + } + ], + 'filter': { + 'term': { + 'layer': 'venue' + } + } + } + }, + { + 'bool': { + '_name': 'fallback.locality', + 'must': [ + { + 'multi_match': { + 'query': 'city value', + 'type': 'phrase', + 'fields': [ + 'parent.locality', + 'parent.locality_a' + ] + } + }, + { + 'multi_match': { + 'query': 'country value', + 'type': 'phrase', + 'fields': [ + 'parent.country', + 'parent.country_a', + 'parent.dependency', + 'parent.dependency_a' + ] + } + } + ], + 'filter': { + 'term': { + 'layer': 'locality' + } + } + } + }, + { + 'bool': { + '_name': 'fallback.localadmin', + 'must': [ + { + 'multi_match': { + 'query': 'city value', + 'type': 'phrase', + 'fields': [ + 'parent.localadmin', + 'parent.localadmin_a' + ] + } + }, + { + 'multi_match': { + 'query': 'country value', + 'type': 'phrase', + 'fields': [ + 'parent.country', + 'parent.country_a', + 'parent.dependency', + 'parent.dependency_a' + ] + } + } + ], + 'filter': { + 'term': { + 'layer': 'localadmin' + } + } + } + }, + { + 'bool': { + '_name': 'fallback.dependency', + 'must': [ + { + 'multi_match': { + 'query': 'country value', + 'type': 'phrase', + 'fields': [ + 'parent.dependency', + 'parent.dependency_a' + ] + } + } + ], + 'filter': { + 'term': { + 'layer': 'dependency' + } + } + } + }, + { + 'bool': { + '_name': 'fallback.country', + 'must': [ + { + 'multi_match': { + 'query': 'country value', + 'type': 'phrase', + 'fields': [ + 'parent.country', + 'parent.country_a' + ] + } + } + ], + 'filter': { + 'term': { + 'layer': 'country' + } + } + } + } + ] + } + }, + 'max_boost': 20, + 'functions': [ + { + 'field_value_factor': { + 'modifier': 'log1p', + 'field': 'popularity', + 'missing': 1 + }, + 'weight': 1 + }, + { + 'field_value_factor': { + 'modifier': 'log1p', + 'field': 'population', + 'missing': 1 + }, + 'weight': 2 + } + ], + 'score_mode': 'avg', + 'boost_mode': 'multiply' + } + }, + 'sort': [ + '_score' + ], + 'size': 20, + 'track_scores': true +}; \ No newline at end of file diff --git a/test/unit/fixture/search_fallback_venue_city_state.js b/test/unit/fixture/search_fallback_venue_city_state.js new file mode 100644 index 000000000..b335ebff7 --- /dev/null +++ b/test/unit/fixture/search_fallback_venue_city_state.js @@ -0,0 +1,196 @@ +module.exports = { + 'query': { + 'function_score': { + 'query': { + 'bool': { + 'minimum_should_match': 1, + 'should': [ + { + 'bool': { + '_name': 'fallback.venue', + 'must': [ + { + 'multi_match': { + 'query': 'query value', + 'type': 'phrase', + 'fields': [ + 'phrase.default' + ] + } + }, + { + 'multi_match': { + 'query': 'city value', + 'type': 'phrase', + 'fields': [ + 'parent.locality', + 'parent.locality_a', + 'parent.localadmin', + 'parent.localadmin_a' + ] + } + }, + { + 'multi_match': { + 'query': 'state value', + 'type': 'phrase', + 'fields': [ + 'parent.region', + 'parent.region_a', + 'parent.macroregion', + 'parent.macroregion_a' + ] + } + } + ], + 'filter': { + 'term': { + 'layer': 'venue' + } + } + } + }, + { + 'bool': { + '_name': 'fallback.locality', + 'must': [ + { + 'multi_match': { + 'query': 'city value', + 'type': 'phrase', + 'fields': [ + 'parent.locality', + 'parent.locality_a' + ] + } + }, + { + 'multi_match': { + 'query': 'state value', + 'type': 'phrase', + 'fields': [ + 'parent.region', + 'parent.region_a', + 'parent.macroregion', + 'parent.macroregion_a' + ] + } + } + ], + 'filter': { + 'term': { + 'layer': 'locality' + } + } + } + }, + { + 'bool': { + '_name': 'fallback.localadmin', + 'must': [ + { + 'multi_match': { + 'query': 'city value', + 'type': 'phrase', + 'fields': [ + 'parent.localadmin', + 'parent.localadmin_a' + ] + } + }, + { + 'multi_match': { + 'query': 'state value', + 'type': 'phrase', + 'fields': [ + 'parent.region', + 'parent.region_a', + 'parent.macroregion', + 'parent.macroregion_a' + ] + } + } + ], + 'filter': { + 'term': { + 'layer': 'localadmin' + } + } + } + }, + { + 'bool': { + '_name': 'fallback.region', + 'must': [ + { + 'multi_match': { + 'query': 'state value', + 'type': 'phrase', + 'fields': [ + 'parent.region', + 'parent.region_a' + ] + } + } + ], + 'filter': { + 'term': { + 'layer': 'region' + } + } + } + }, + { + 'bool': { + '_name': 'fallback.macroregion', + 'must': [ + { + 'multi_match': { + 'query': 'state value', + 'type': 'phrase', + 'fields': [ + 'parent.macroregion', + 'parent.macroregion_a' + ] + } + } + ], + 'filter': { + 'term': { + 'layer': 'macroregion' + } + } + } + } + ] + } + }, + 'max_boost': 20, + 'functions': [ + { + 'field_value_factor': { + 'modifier': 'log1p', + 'field': 'popularity', + 'missing': 1 + }, + 'weight': 1 + }, + { + 'field_value_factor': { + 'modifier': 'log1p', + 'field': 'population', + 'missing': 1 + }, + 'weight': 2 + } + ], + 'score_mode': 'avg', + 'boost_mode': 'multiply' + } + }, + 'sort': [ + '_score' + ], + 'size': 20, + 'track_scores': true +}; \ No newline at end of file diff --git a/test/unit/query/search.js b/test/unit/query/search.js index 5dac3bd93..a05058834 100644 --- a/test/unit/query/search.js +++ b/test/unit/query/search.js @@ -316,7 +316,12 @@ module.exports.tests.city_state = function(test, common) { var query = generate(clean); - t.equals(query, undefined, 'should have returned undefined'); + var compiled = JSON.parse(JSON.stringify(query)); + var expected = require('../fixture/search_fallback_venue_city_state'); + + t.deepEqual(compiled.type, 'search_fallback', 'query type set'); + t.deepEqual(compiled.body, expected, 'search_fallback_venue_city_state'); + t.end(); }); @@ -475,7 +480,12 @@ module.exports.tests.city_country = function(test, common) { var query = generate(clean); - t.equals(query, undefined, 'should have returned undefined'); + var compiled = JSON.parse(JSON.stringify(query)); + var expected = require('../fixture/search_fallback_venue_city_country'); + + t.deepEqual(compiled.type, 'search_fallback', 'query type set'); + t.deepEqual(compiled.body, expected, 'search_fallback_venue_city_country'); + t.end(); });