From: Sarah Hoffmann Date: Tue, 17 Nov 2020 17:03:33 +0000 (+0100) Subject: split addr: tags into words before adding to the search index X-Git-Tag: v3.6.0~29^2 X-Git-Url: https://git.openstreetmap.org./nominatim.git/commitdiff_plain/30a6b6bdac5806051741b771d5ad8ad2c976aac9?hp=cc345f531ac81b3ebc85452accc433a753c61868 split addr: tags into words before adding to the search index Address parts are only matched by single partial words. If the addr: names are not split, then multi-word names cannot be found. --- diff --git a/sql/functions/normalization.sql b/sql/functions/normalization.sql index b2fecab7..a5560cb9 100644 --- a/sql/functions/normalization.sql +++ b/sql/functions/normalization.sql @@ -207,19 +207,31 @@ CREATE OR REPLACE FUNCTION addr_ids_from_name(lookup_word TEXT) RETURNS INTEGER[] AS $$ DECLARE - lookup_token TEXT; + words TEXT[]; id INTEGER; return_word_id INTEGER[]; + word_ids INTEGER[]; + j INTEGER; BEGIN - lookup_token := make_standard_name(lookup_word); - SELECT array_agg(word_id) FROM word - WHERE word_token = lookup_token and class is null and type is null - INTO return_word_id; - IF return_word_id IS NULL THEN - id := nextval('seq_word'); - INSERT INTO word VALUES (id, lookup_token, null, null, null, null, 0); - return_word_id = ARRAY[id]; + words := string_to_array(make_standard_name(lookup_word), ' '); + IF array_upper(words, 1) IS NOT NULL THEN + FOR j IN 1..array_upper(words, 1) LOOP + IF (words[j] != '') THEN + SELECT array_agg(word_id) INTO word_ids + FROM word + WHERE word_token = words[j] and class is null and type is null; + + IF word_ids IS NULL THEN + id := nextval('seq_word'); + INSERT INTO word VALUES (id, words[j], null, null, null, null, 0); + return_word_id := return_word_id || id; + ELSE + return_word_id := array_merge(return_word_id, word_ids); + END IF; + END IF; + END LOOP; END IF; + RETURN return_word_id; END; $$ diff --git a/test/bdd/db/import/search_name.feature b/test/bdd/db/import/search_name.feature index 866a597d..beae3444 100644 --- a/test/bdd/db/import/search_name.feature +++ b/test/bdd/db/import/search_name.feature @@ -30,7 +30,24 @@ Feature: Creation of search terms | osm_type | osm_id | name | | N | 1 | 23, Rose Street | - Scenario: Unnamed POI has no search entry when it has known addr: tags + Scenario: Searching for unknown addr: tags also works for multiple words + Given the scene roads-with-pois + And the places + | osm | class | type | housenr | addr+city | geometry | + | N1 | place | house | 23 | Little Big Town | :p-N1 | + And the places + | osm | class | type | name+name | geometry | + | W1 | highway | residential | Rose Street | :w-north | + When importing + Then search_name contains + | object | name_vector | nameaddress_vector | + | N1 | #23 | Rose Street, Little, Big, Town | + When searching for "23 Rose Street, Little Big Town" + Then results contain + | osm_type | osm_id | name | + | N | 1 | 23, Rose Street | + + Scenario: Unnamed POI has no search entry when it has known addr: tags Given the scene roads-with-pois And the places | osm | class | type | housenr | addr+city | geometry | @@ -197,7 +214,7 @@ Feature: Creation of search terms When importing Then search_name contains | object | nameaddress_vector | - | W1 | bonn, new york, smalltown | + | W1 | bonn, new, york, smalltown | Scenario: A known addr:* tag is added even if the name is unknown Given the scene roads-with-pois