forked from hans/Nominatim
move name token creation into tokenizer
Name tokens are now handed in via token_info and used from there. Also moves the generic search name insertion function back to placex_triggers.sql.
This commit is contained in:
@@ -1,3 +1,31 @@
|
||||
-- Get tokens used for searching the given place.
|
||||
--
|
||||
-- These are the tokens that will be saved in the search_name table.
|
||||
CREATE OR REPLACE FUNCTION token_get_name_search_tokens(info JSONB)
|
||||
RETURNS INTEGER[]
|
||||
AS $$
|
||||
SELECT (info->>'names')::INTEGER[]
|
||||
$$ LANGUAGE SQL IMMUTABLE STRICT;
|
||||
|
||||
-- Get tokens for matching the place name against others.
|
||||
--
|
||||
-- This should usually be restricted to full name tokens.
|
||||
CREATE OR REPLACE FUNCTION token_get_name_match_tokens(info JSONB)
|
||||
RETURNS INTEGER[]
|
||||
AS $$
|
||||
SELECT (info->>'names')::INTEGER[]
|
||||
$$ LANGUAGE SQL IMMUTABLE STRICT;
|
||||
|
||||
|
||||
-- Return token info that should be saved permanently in the database.
|
||||
CREATE OR REPLACE FUNCTION token_strip_info(info JSONB)
|
||||
RETURNS JSONB
|
||||
AS $$
|
||||
SELECT NULL::JSONB;
|
||||
$$ LANGUAGE SQL IMMUTABLE STRICT;
|
||||
|
||||
--------------- private functions ----------------------------------------------
|
||||
|
||||
-- Functions for term normalisation and access to the 'word' table.
|
||||
|
||||
CREATE OR REPLACE FUNCTION transliteration(text) RETURNS text
|
||||
@@ -423,103 +451,3 @@ BEGIN
|
||||
END;
|
||||
$$
|
||||
LANGUAGE plpgsql;
|
||||
|
||||
|
||||
CREATE OR REPLACE FUNCTION create_poi_search_terms(obj_place_id BIGINT,
|
||||
in_partition SMALLINT,
|
||||
parent_place_id BIGINT,
|
||||
address HSTORE,
|
||||
country TEXT,
|
||||
housenumber TEXT,
|
||||
initial_name_vector INTEGER[],
|
||||
geometry GEOMETRY,
|
||||
OUT name_vector INTEGER[],
|
||||
OUT nameaddress_vector INTEGER[])
|
||||
AS $$
|
||||
DECLARE
|
||||
parent_name_vector INTEGER[];
|
||||
parent_address_vector INTEGER[];
|
||||
addr_place_ids INTEGER[];
|
||||
|
||||
addr_item RECORD;
|
||||
parent_address_place_ids BIGINT[];
|
||||
filtered_address HSTORE;
|
||||
BEGIN
|
||||
nameaddress_vector := '{}'::INTEGER[];
|
||||
|
||||
SELECT s.name_vector, s.nameaddress_vector
|
||||
INTO parent_name_vector, parent_address_vector
|
||||
FROM search_name s
|
||||
WHERE s.place_id = parent_place_id;
|
||||
|
||||
-- Find all address tags that don't appear in the parent search names.
|
||||
SELECT hstore(array_agg(ARRAY[k, v])) INTO filtered_address
|
||||
FROM (SELECT skeys(address) as k, svals(address) as v) a
|
||||
WHERE not addr_ids_from_name(v) && parent_address_vector
|
||||
AND k not in ('country', 'street', 'place', 'postcode',
|
||||
'housenumber', 'streetnumber', 'conscriptionnumber');
|
||||
|
||||
-- Compute all search terms from the addr: tags.
|
||||
IF filtered_address IS NOT NULL THEN
|
||||
FOR addr_item IN
|
||||
SELECT * FROM
|
||||
get_places_for_addr_tags(in_partition, geometry, filtered_address, country)
|
||||
LOOP
|
||||
IF addr_item.place_id is null THEN
|
||||
nameaddress_vector := array_merge(nameaddress_vector,
|
||||
addr_item.keywords);
|
||||
CONTINUE;
|
||||
END IF;
|
||||
|
||||
IF parent_address_place_ids is null THEN
|
||||
SELECT array_agg(parent_place_id) INTO parent_address_place_ids
|
||||
FROM place_addressline
|
||||
WHERE place_id = parent_place_id;
|
||||
END IF;
|
||||
|
||||
IF not parent_address_place_ids @> ARRAY[addr_item.place_id] THEN
|
||||
nameaddress_vector := array_merge(nameaddress_vector,
|
||||
addr_item.keywords);
|
||||
|
||||
INSERT INTO place_addressline (place_id, address_place_id, fromarea,
|
||||
isaddress, distance, cached_rank_address)
|
||||
VALUES (obj_place_id, addr_item.place_id, not addr_item.isguess,
|
||||
true, addr_item.distance, addr_item.rank_address);
|
||||
END IF;
|
||||
END LOOP;
|
||||
END IF;
|
||||
|
||||
name_vector := initial_name_vector;
|
||||
|
||||
-- Check if the parent covers all address terms.
|
||||
-- If not, create a search name entry with the house number as the name.
|
||||
-- This is unusual for the search_name table but prevents that the place
|
||||
-- is returned when we only search for the street/place.
|
||||
|
||||
IF housenumber is not null and not nameaddress_vector <@ parent_address_vector THEN
|
||||
name_vector := array_merge(name_vector,
|
||||
ARRAY[getorcreate_housenumber_id(make_standard_name(housenumber))]);
|
||||
END IF;
|
||||
|
||||
IF not address ? 'street' and address ? 'place' THEN
|
||||
addr_place_ids := addr_ids_from_name(address->'place');
|
||||
IF not addr_place_ids <@ parent_name_vector THEN
|
||||
-- make sure addr:place terms are always searchable
|
||||
nameaddress_vector := array_merge(nameaddress_vector, addr_place_ids);
|
||||
-- If there is a housenumber, also add the place name as a name,
|
||||
-- so we can search it by the usual housenumber+place algorithms.
|
||||
IF housenumber is not null THEN
|
||||
name_vector := array_merge(name_vector,
|
||||
ARRAY[getorcreate_name_id(make_standard_name(address->'place'))]);
|
||||
END IF;
|
||||
END IF;
|
||||
END IF;
|
||||
|
||||
-- Cheating here by not recomputing all terms but simply using the ones
|
||||
-- from the parent object.
|
||||
nameaddress_vector := array_merge(nameaddress_vector, parent_name_vector);
|
||||
nameaddress_vector := array_merge(nameaddress_vector, parent_address_vector);
|
||||
|
||||
END;
|
||||
$$
|
||||
LANGUAGE plpgsql;
|
||||
|
||||
Reference in New Issue
Block a user