]> git.openstreetmap.org Git - nominatim.git/commitdiff
do not lookup by address vector when only few tokens are available
authorSarah Hoffmann <lonvia@denofr.de>
Mon, 31 Jul 2023 12:27:39 +0000 (14:27 +0200)
committerSarah Hoffmann <lonvia@denofr.de>
Wed, 2 Aug 2023 07:25:47 +0000 (09:25 +0200)
Names of countries and states are exceedingly rare in the word count
but are very frequent in the address. A short name has the danger
of producing too many results.

nominatim/api/search/db_search_builder.py
test/python/api/search/test_db_search_builder.py

index fc444aa25439421f7bd146b2f412f926b8efc511..7c6d13f09dbd9fbeacac4b631f2a04f8be280cfa 100644 (file)
@@ -212,7 +212,7 @@ class SearchBuilder:
 
         exp_count = min(exp_count, min(t.count for t in addr_partials)) \
                     if addr_partials else exp_count
-        if exp_count < 1000 and partials_indexed:
+        if exp_count < 1000 and len(addr_tokens) > 3 and partials_indexed:
             # Lookup by address partials and restrict results through name terms.
             # Give this a small penalty because lookups in the address index are
             # more expensive
index 63589ffc02cd546145734efffffb357132e1e541..0e5a8bfcd47d0b8ac13fa36a6290d1c383b5b858 100644 (file)
@@ -332,9 +332,10 @@ def test_name_only_search_with_countries():
     assert not search.housenumbers.values
 
 
-def make_counted_searches(name_part, name_full, address_part, address_full):
+def make_counted_searches(name_part, name_full, address_part, address_full,
+                          num_address_parts=1):
     q = QueryStruct([Phrase(PhraseType.NONE, '')])
-    for i in range(2):
+    for i in range(1 + num_address_parts):
         q.add_node(BreakType.WORD, PhraseType.NONE)
     q.add_node(BreakType.END, PhraseType.NONE)
 
@@ -342,15 +343,16 @@ def make_counted_searches(name_part, name_full, address_part, address_full):
                 MyToken(0.5, 1, name_part, 'name_part', True))
     q.add_token(TokenRange(0, 1), TokenType.WORD,
                 MyToken(0, 101, name_full, 'name_full', True))
-    q.add_token(TokenRange(1, 2), TokenType.PARTIAL,
-                MyToken(0.5, 2, address_part, 'address_part', True))
-    q.add_token(TokenRange(1, 2), TokenType.WORD,
-                MyToken(0, 102, address_full, 'address_full', True))
+    for i in range(num_address_parts):
+        q.add_token(TokenRange(i + 1, i + 2), TokenType.PARTIAL,
+                    MyToken(0.5, 2, address_part, 'address_part', True))
+        q.add_token(TokenRange(i + 1, i + 2), TokenType.WORD,
+                    MyToken(0, 102, address_full, 'address_full', True))
 
     builder = SearchBuilder(q, SearchDetails())
 
     return list(builder.build(TokenAssignment(name=TokenRange(0, 1),
-                                              address=[TokenRange(1, 2)])))
+                                              address=[TokenRange(1, 1 + num_address_parts)])))
 
 
 def test_infrequent_partials_in_name():
@@ -368,7 +370,7 @@ def test_infrequent_partials_in_name():
 
 
 def test_frequent_partials_in_name_but_not_in_address():
-    searches = make_counted_searches(10000, 1, 1, 1)
+    searches = make_counted_searches(10000, 1, 1, 1, num_address_parts=4)
 
     assert len(searches) == 1
     search = searches[0]