]> git.openstreetmap.org Git - nominatim.git/blobdiff - nominatim/api/search/db_searches.py
extend word statistics to address index
[nominatim.git] / nominatim / api / search / db_searches.py
index 254d2ca6703e8f20c4056a694b8a15c4353e841a..3f294de7c925ba5b2017bfd247496ef2c28c189c 100644 (file)
@@ -5,7 +5,7 @@
 # Copyright (C) 2023 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 # Copyright (C) 2023 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
-Implementation of the acutal database accesses for forward search.
+Implementation of the actual database accesses for forward search.
 """
 from typing import List, Tuple, AsyncIterator, Dict, Any, Callable, cast
 import abc
 """
 from typing import List, Tuple, AsyncIterator, Dict, Any, Callable, cast
 import abc
@@ -245,6 +245,7 @@ async def _get_tiger(conn: SearchConnection, place_ids: List[int],
 class AbstractSearch(abc.ABC):
     """ Encapuslation of a single lookup in the database.
     """
 class AbstractSearch(abc.ABC):
     """ Encapuslation of a single lookup in the database.
     """
+    SEARCH_PRIO: int = 2
 
     def __init__(self, penalty: float) -> None:
         self.penalty = penalty
 
     def __init__(self, penalty: float) -> None:
         self.penalty = penalty
@@ -448,6 +449,8 @@ class PoiSearch(AbstractSearch):
 class CountrySearch(AbstractSearch):
     """ Search for a country name or country code.
     """
 class CountrySearch(AbstractSearch):
     """ Search for a country name or country code.
     """
+    SEARCH_PRIO = 0
+
     def __init__(self, sdata: SearchData) -> None:
         super().__init__(sdata.penalty)
         self.countries = sdata.countries
     def __init__(self, sdata: SearchData) -> None:
         super().__init__(sdata.penalty)
         self.countries = sdata.countries
@@ -481,7 +484,14 @@ class CountrySearch(AbstractSearch):
             result.bbox = Bbox.from_wkb(row.bbox)
             results.append(result)
 
             result.bbox = Bbox.from_wkb(row.bbox)
             results.append(result)
 
-        return results or await self.lookup_in_country_table(conn, details)
+        if not results:
+            results = await self.lookup_in_country_table(conn, details)
+
+        if results:
+            details.min_rank = min(5, details.max_rank)
+            details.max_rank = min(25, details.max_rank)
+
+        return results
 
 
     async def lookup_in_country_table(self, conn: SearchConnection,
 
 
     async def lookup_in_country_table(self, conn: SearchConnection,
@@ -592,10 +602,28 @@ class PostcodeSearch(AbstractSearch):
 
         results = nres.SearchResults()
         for row in await conn.execute(sql, _details_to_bind_params(details)):
 
         results = nres.SearchResults()
         for row in await conn.execute(sql, _details_to_bind_params(details)):
-            result = nres.create_from_postcode_row(row, nres.SearchResult)
+            p = conn.t.placex
+            placex_sql = _select_placex(p).add_columns(p.c.importance)\
+                             .where(sa.text("""class = 'boundary'
+                                               AND type = 'postal_code'
+                                               AND osm_type = 'R'"""))\
+                             .where(p.c.country_code == row.country_code)\
+                             .where(p.c.postcode == row.postcode)\
+                             .limit(1)
+
+            if details.geometry_output:
+                placex_sql = _add_geometry_columns(placex_sql, p.c.geometry, details)
+
+            for prow in await conn.execute(placex_sql, _details_to_bind_params(details)):
+                result = nres.create_from_placex_row(prow, nres.SearchResult)
+                break
+            else:
+                result = nres.create_from_postcode_row(row, nres.SearchResult)
+
             assert result
             assert result
-            result.accuracy = row.accuracy
-            results.append(result)
+            if result.place_id not in details.excluded:
+                result.accuracy = row.accuracy
+                results.append(result)
 
         return results
 
 
         return results
 
@@ -604,6 +632,8 @@ class PostcodeSearch(AbstractSearch):
 class PlaceSearch(AbstractSearch):
     """ Generic search for an address or named place.
     """
 class PlaceSearch(AbstractSearch):
     """ Generic search for an address or named place.
     """
+    SEARCH_PRIO = 1
+
     def __init__(self, extra_penalty: float, sdata: SearchData, expected_count: int) -> None:
         super().__init__(sdata.penalty + extra_penalty)
         self.countries = sdata.countries
     def __init__(self, extra_penalty: float, sdata: SearchData, expected_count: int) -> None:
         super().__init__(sdata.penalty + extra_penalty)
         self.countries = sdata.countries
@@ -688,7 +718,7 @@ class PlaceSearch(AbstractSearch):
                or (details.viewbox is not None and details.viewbox.area < 0.5):
                 sql = sql.order_by(
                         penalty - sa.case((tsearch.c.importance > 0, tsearch.c.importance),
                or (details.viewbox is not None and details.viewbox.area < 0.5):
                 sql = sql.order_by(
                         penalty - sa.case((tsearch.c.importance > 0, tsearch.c.importance),
-                                    else_=0.75001-(sa.cast(tsearch.c.search_rank, sa.Float())/40)))
+                                    else_=0.40001-(sa.cast(tsearch.c.search_rank, sa.Float())/75)))
             sql = sql.add_columns(t.c.importance)
 
 
             sql = sql.add_columns(t.c.importance)