From d0a1e8e3110bfe3dea221933ab4e8964e8d74f66 Mon Sep 17 00:00:00 2001
From: Sarah Hoffmann
Date: Tue, 20 Jun 2023 10:54:04 +0200
Subject: [PATCH] tweak postcode search
Give a preference to left-right reading, i.e ,
prefers a postcode search while , rather does
an address search.
Also exclude non-addressables, countries and state from results when a
postcode is contained in the query.
---
nominatim/api/logging.py | 2 +-
nominatim/api/search/db_search_builder.py | 4 +++-
nominatim/api/search/db_searches.py | 2 ++
nominatim/api/search/token_assignment.py | 10 +++++++++-
test/python/api/search/test_token_assignment.py | 4 ++--
5 files changed, 17 insertions(+), 5 deletions(-)
diff --git a/nominatim/api/logging.py b/nominatim/api/logging.py
index a4da357d..6c8b1b38 100644
--- a/nominatim/api/logging.py
+++ b/nominatim/api/logging.py
@@ -178,7 +178,7 @@ class HTMLLogger(BaseLogger):
self._write(f"rank={res.rank_address}, ")
self._write(f"osm={format_osm(res.osm_object)}, ")
self._write(f'cc={res.country_code}, ')
- self._write(f'importance={res.importance or -1:.5f})')
+ self._write(f'importance={res.importance or float("nan"):.5f})')
total += 1
self._write(f'TOTAL: {total}
')
diff --git a/nominatim/api/search/db_search_builder.py b/nominatim/api/search/db_search_builder.py
index b6ba211c..9ff8c03c 100644
--- a/nominatim/api/search/db_search_builder.py
+++ b/nominatim/api/search/db_search_builder.py
@@ -141,12 +141,14 @@ class SearchBuilder:
yield dbs.CountrySearch(sdata)
if sdata.postcodes and (is_category or self.configured_for_postcode):
+ penalty = 0.0 if sdata.countries else 0.1
if address:
sdata.lookups = [dbf.FieldLookup('nameaddress_vector',
[t.token for r in address
for t in self.query.get_partials_list(r)],
'restrict')]
- yield dbs.PostcodeSearch(0.4, sdata)
+ penalty += 0.2
+ yield dbs.PostcodeSearch(penalty, sdata)
def build_housenumber_search(self, sdata: dbf.SearchData, hnrs: List[Token],
diff --git a/nominatim/api/search/db_searches.py b/nominatim/api/search/db_searches.py
index db35f726..ba4a3995 100644
--- a/nominatim/api/search/db_searches.py
+++ b/nominatim/api/search/db_searches.py
@@ -562,6 +562,8 @@ class PlaceSearch(AbstractSearch):
sql = sql.where(tsearch.c.country_code.in_(self.countries.values))
if self.postcodes:
+ # if a postcode is given, don't search for state or country level objects
+ sql = sql.where(tsearch.c.address_rank > 9)
tpc = conn.t.postcode
if self.expected_count > 1000:
# Many results expected. Restrict by postcode.
diff --git a/nominatim/api/search/token_assignment.py b/nominatim/api/search/token_assignment.py
index 747fea6c..11da2359 100644
--- a/nominatim/api/search/token_assignment.py
+++ b/nominatim/api/search/token_assignment.py
@@ -270,7 +270,12 @@ class _TokenSequence:
if (base.postcode.start == 0 and self.direction != -1)\
or (base.postcode.end == query.num_token_slots() and self.direction != 1):
log().comment('postcode search')
- yield dataclasses.replace(base, penalty=self.penalty)
+ # , should give preference to address search
+ if base.postcode.start == 0:
+ penalty = self.penalty
+ else:
+ penalty = self.penalty + 0.1
+ yield dataclasses.replace(base, penalty=penalty)
# Postcode or country-only search
if not base.address:
@@ -278,6 +283,9 @@ class _TokenSequence:
log().comment('postcode/country search')
yield dataclasses.replace(base, penalty=self.penalty)
else:
+ # , should give preference to postcode search
+ if base.postcode and base.postcode.start == 0:
+ self.penalty += 0.1
# Use entire first word as name
if self.direction != -1:
log().comment('first word = name')
diff --git a/test/python/api/search/test_token_assignment.py b/test/python/api/search/test_token_assignment.py
index f78d5430..dc123403 100644
--- a/test/python/api/search/test_token_assignment.py
+++ b/test/python/api/search/test_token_assignment.py
@@ -253,7 +253,7 @@ def test_postcode_with_designation():
(BreakType.PHRASE, PhraseType.NONE, [(2, TokenType.PARTIAL)]))
check_assignments(yield_token_assignments(q),
- TokenAssignment(name=TokenRange(1, 2),
+ TokenAssignment(penalty=0.1, name=TokenRange(1, 2),
postcode=TokenRange(0, 1)),
TokenAssignment(postcode=TokenRange(0, 1),
address=[TokenRange(1, 2)]))
@@ -266,7 +266,7 @@ def test_postcode_with_designation_backwards():
check_assignments(yield_token_assignments(q),
TokenAssignment(name=TokenRange(0, 1),
postcode=TokenRange(1, 2)),
- TokenAssignment(postcode=TokenRange(1, 2),
+ TokenAssignment(penalty=0.1, postcode=TokenRange(1, 2),
address=[TokenRange(0, 1)]))
--
2.39.5