]> git.openstreetmap.org Git - nominatim.git/commitdiff
Merge pull request #2429 from lonvia/place-name-to-admin-boundary
authorSarah Hoffmann <lonvia@denofr.de>
Sat, 21 Aug 2021 08:21:39 +0000 (10:21 +0200)
committerGitHub <noreply@github.com>
Sat, 21 Aug 2021 08:21:39 +0000 (10:21 +0200)
Indexing: move linking of places to the preparation stage

lib-sql/functions/placex_triggers.sql
nominatim/indexer/runners.py
test/bdd/db/query/linking.feature [new file with mode: 0644]
test/python/test_indexing.py

index e3be9503aa84eadca65e2f74d07e6e7aa5835d4b..fa7156ec904c396a8376b780d03c09a37045fb43 100644 (file)
 CREATE OR REPLACE FUNCTION placex_prepare_update(p placex,
                                                  OUT name HSTORE,
                                                  OUT address HSTORE,
-                                                 OUT country_feature VARCHAR)
+                                                 OUT country_feature VARCHAR,
+                                                 OUT linked_place_id BIGINT)
   AS $$
+DECLARE
+  location RECORD;
 BEGIN
   -- For POI nodes, check if the address should be derived from a surrounding
   -- building.
@@ -34,6 +37,18 @@ BEGIN
   address := address - '_unlisted_place'::TEXT;
   name := p.name;
 
+  -- Names of linked places need to be merged in, so search for a linkable
+  -- place already here.
+  SELECT * INTO location FROM find_linked_place(p);
+
+  IF location.place_id is not NULL THEN
+    linked_place_id := location.place_id;
+
+    IF NOT location.name IS NULL THEN
+      name := location.name || name;
+    END IF;
+  END IF;
+
   country_feature := CASE WHEN p.admin_level = 2
                                and p.class = 'boundary' and p.type = 'administrative'
                                and p.osm_type = 'R'
@@ -683,6 +698,8 @@ DECLARE
   nameaddress_vector INTEGER[];
   addr_nameaddress_vector INTEGER[];
 
+  linked_place BIGINT;
+
   linked_node_id BIGINT;
   linked_importance FLOAT;
   linked_wikipedia TEXT;
@@ -718,9 +735,14 @@ BEGIN
 
   NEW.extratags := NEW.extratags - 'linked_place'::TEXT;
 
+  -- NEW.linked_place_id contains the precomputed linkee. Save this and restore
+  -- the previous link status.
+  linked_place := NEW.linked_place_id;
+  NEW.linked_place_id := OLD.linked_place_id;
+
   IF NEW.linked_place_id is not null THEN
     NEW.token_info := null;
-    {% if debug %}RAISE WARNING 'place already linked to %', NEW.linked_place_id;{% endif %}
+    {% if debug %}RAISE WARNING 'place already linked to %', OLD.linked_place_id;{% endif %}
     RETURN NEW;
   END IF;
 
@@ -956,8 +978,9 @@ BEGIN
   -- ---------------------------------------------------------------------------
   -- Full indexing
   {% if debug %}RAISE WARNING 'Using full index mode for % %', NEW.osm_type, NEW.osm_id;{% endif %}
-  SELECT * INTO location FROM find_linked_place(NEW);
-  IF location.place_id is not null THEN
+  IF linked_place is not null THEN
+    SELECT * INTO location FROM placex WHERE place_id = linked_place;
+
     {% if debug %}RAISE WARNING 'Linked %', location;{% endif %}
 
     -- Use the linked point as the centre point of the geometry,
@@ -974,11 +997,6 @@ BEGIN
       NEW.rank_address := location.rank_address;
     END IF;
 
-    -- merge in the label name
-    IF NOT location.name IS NULL THEN
-      NEW.name := location.name || NEW.name;
-    END IF;
-
     -- merge in extra tags
     NEW.extratags := hstore('linked_' || location.class, location.type)
                      || coalesce(location.extratags, ''::hstore)
index 068d7d0fa63edba9a45fe7aef9195d06d164996a..29261ee50ebe59aac57a260e560a6016036e5139 100644 (file)
@@ -16,6 +16,7 @@ class AbstractPlacexRunner:
     """ Returns SQL commands for indexing of the placex table.
     """
     SELECT_SQL = pysql.SQL('SELECT place_id FROM placex ')
+    UPDATE_LINE = "(%s, %s::hstore, %s::hstore, %s::int, %s::jsonb)"
 
     def __init__(self, rank, analyzer):
         self.rank = rank
@@ -27,10 +28,11 @@ class AbstractPlacexRunner:
     def _index_sql(num_places):
         return pysql.SQL(
             """ UPDATE placex
-                SET indexed_status = 0, address = v.addr, token_info = v.ti
-                FROM (VALUES {}) as v(id, addr, ti)
+                SET indexed_status = 0, address = v.addr, token_info = v.ti,
+                    name = v.name, linked_place_id = v.linked_place_id
+                FROM (VALUES {}) as v(id, name, addr, linked_place_id, ti)
                 WHERE place_id = v.id
-            """).format(_mk_valuelist("(%s, %s::hstore, %s::jsonb)", num_places))
+            """).format(_mk_valuelist(AbstractPlacexRunner.UPDATE_LINE, num_places))
 
 
     @staticmethod
@@ -43,7 +45,8 @@ class AbstractPlacexRunner:
     def index_places(self, worker, places):
         values = []
         for place in places:
-            values.extend((place[x] for x in ('place_id', 'address')))
+            for field in ('place_id', 'name', 'address', 'linked_place_id'):
+                values.append(place[field])
             values.append(psycopg2.extras.Json(self.analyzer.process_place(place)))
 
         worker.perform(self._index_sql(len(places)), values)
diff --git a/test/bdd/db/query/linking.feature b/test/bdd/db/query/linking.feature
new file mode 100644 (file)
index 0000000..4e6c47d
--- /dev/null
@@ -0,0 +1,22 @@
+@DB
+Feature: Searching linked places
+    Tests that information from linked places can be searched correctly
+
+    Scenario: Additional names from linked places are searchable
+        Given the places
+         | osm  | class    | type           | admin | name  | geometry |
+         | R13  | boundary | administrative | 6     | Garbo | poly-area:0.1 |
+        Given the places
+         | osm  | class    | type           | admin | name+name:it | geometry |
+         | N2   | place    | hamlet         | 15    | Vario        | 0.006 0.00001 |
+        And the relations
+         | id | members       | tags+type |
+         | 13 | N2:label      | boundary |
+        When importing
+        Then placex contains
+         | object  | linked_place_id |
+         | N2      | R13 |
+        When sending search query "Vario"
+        Then results contain
+         | osm |
+         | R13 |
index 9873e7d72673a8aaeb3e356276a4b558d97be3e8..60ad0bc4cbd3c5705891c60c847809ba74d7b985 100644 (file)
@@ -19,8 +19,10 @@ class IndexerTestDB:
         with self.conn.cursor() as cur:
             cur.execute('CREATE EXTENSION hstore')
             cur.execute("""CREATE TABLE placex (place_id BIGINT,
+                                                name HSTORE,
                                                 class TEXT,
                                                 type TEXT,
+                                                linked_place_id BIGINT,
                                                 rank_address SMALLINT,
                                                 rank_search SMALLINT,
                                                 indexed_status SMALLINT,
@@ -55,11 +57,12 @@ class IndexerTestDB:
             cur.execute("""CREATE OR REPLACE FUNCTION placex_prepare_update(p placex,
                                                       OUT name HSTORE,
                                                       OUT address HSTORE,
-                                                      OUT country_feature VARCHAR)
+                                                      OUT country_feature VARCHAR,
+                                                      OUT linked_place_id BIGINT)
                            AS $$
                            BEGIN
                             address := p.address;
-                            name := p.address;
+                            name := p.name;
                            END;
                            $$ LANGUAGE plpgsql STABLE;
                         """)