Parsování adres v PostgreSQL

studentX

Parsování adres v PostgreSQL
« kdy: 23. 01. 2017, 14:13:37 »
Ahoj, věděli byste mi prosím poradit jaký je nejlepší způsob parsování adresy z textovího retezce? Mám k dispozici tabulku adres exportovanou z OSM, ve tvaru Points (město, ulice, číslo domu, kód země, početní směrovací číslo, geometry sloupec, ...), a od uživatele textový vstup např. "Olomouc Mrková 15". Tento řetězec bych potřeboval rozparsovat a na základě těchto údajů zvolit bod z tabulky Points s největší podobností. Budu vděčný za každou radu


Petr

Re:Parsování adres v PostgreSQL
« Odpověď #1 kdy: 23. 01. 2017, 14:41:58 »
Fulltext

Trupik

Re:Parsování adres v PostgreSQL
« Odpověď #2 kdy: 23. 01. 2017, 15:18:29 »
Súhlasím, fulltext. Môžeš sa síce snažiť chytristikou zistiť, čo je ulica a čo mesto, ale vo výsledku sa len zložitým postupom dostaneš ku takmer identickému výsledku. Pozor na to, že fulltext v PG funguje inak než v MySQL. Je naozaj nutné začať s manuálom a nestrácať čas štýlom pokus-omyl.

studentX

Re:Parsování adres v PostgreSQL
« Odpověď #3 kdy: 23. 01. 2017, 18:32:38 »
takže mám procházet všechny sloupce v tabulce a hledat jednotlivé hodnoty v řetězci?

Re:Parsování adres v PostgreSQL
« Odpověď #4 kdy: 23. 01. 2017, 19:45:49 »
Uděláš si fulltext index pro Points a pak v něm budeš hledat to, co zadal uživatel (seřadíš dle relevance).


studentX

Re:Parsování adres v PostgreSQL
« Odpověď #5 kdy: 23. 01. 2017, 21:26:33 »
pokud kladu triviální otázky tak se omlouvám, ale nemam mnoho zkušenosti s pgsql

Re:Parsování adres v PostgreSQL
« Odpověď #6 kdy: 24. 01. 2017, 13:50:42 »
Není to složité, ale chce to postupovat podle nějakého návodu. Když už to člověk jednou dělal, je to na chvíli. Už jsem to dlouho nepoužíval, ale postupoval jsem nějak takto:

Kód: [Vybrat]
-------------------------------------------------------------------
How to manage fulltext search in Postgres 9.4:
-------------------------------------------------------------------

1. Copy .affix .dict and .stop files for czech to postgres, for example:

cp -vi postgres-fulltext/* /usr/share/pgsql/tsearch_data/

2. Load these files and create configuration from it:

-- configuration:
DROP TEXT SEARCH CONFIGURATION public.czech;
CREATE TEXT SEARCH CONFIGURATION public.czech ( COPY = pg_catalog.simple ) ;
COMMENT ON TEXT SEARCH CONFIGURATION  public.czech IS 'configuration for czech language';

-- dictionary:
CREATE TEXT SEARCH DICTIONARY czech_ispell (
    TEMPLATE  = ispell,
    DictFile  = czech,
    AffFile   = czech,
    StopWords = czech
);
COMMENT ON TEXT SEARCH DICTIONARY  czech_ispell IS 'ispell for czech language';

-- modify mappings:
ALTER TEXT SEARCH CONFIGURATION czech ALTER MAPPING FOR asciiword, asciihword, hword_asciipart, word, hword, hword_part WITH czech_ispell, simple;
ALTER TEXT SEARCH CONFIGURATION czech DROP  MAPPING FOR email, url, url_path, sfloat, float;

-- List new configurations - works only in psql:
\dF
\dFd
\dFp
\dFt

3. Test new configuration:

SET default_text_search_config = 'public.czech';

SELECT * FROM ts_debug('Příliš žluťoučký kůň úpěl ďábelské ódy.');
SELECT * FROM ts_debug('czech', 'Příliš žluťoučký kůň úpěl ďábelské ódy.');

SELECT * FROM ts_debug('Dlouho jsem přemýšlel, jestli se k tomu přiznávat, ale nakonec jsem si řekl, že jednou to odhalení přijít musí.');
SELECT * FROM ts_debug('czech','Dlouho jsem přemýšlel, jestli se k tomu přiznávat, ale nakonec jsem si řekl, že jednou to odhalení přijít musí.');

4. Set fulltext search configuration permanently:

vim postgresql.conf:
default_text_search_config = 'public.czech'
service postgresql restart

5. Add searchable columns:

ALTER TABLE table ADD COLUMN tsearch_idx tsvector NULL DEFAULT NULL;

6. Add gin index on this column:

DROP INDEX IF EXISTS tsearch_gin_idx;
CREATE INDEX tsearch_gin_idx ON points USING gin(tsearch_idx);

7. Add trigger to keep searchable column up-to-date:

CREATE OR REPLACE FUNCTION update_table_tsearch_idx() RETURNS trigger AS $$
BEGIN
-- NEW.id;
-- (...)
return NEW;
END
$$ LANGUAGE plpgsql;

DROP   TRIGGER update_table_tsearch_idx ON table;
CREATE TRIGGER update_table_tsearch_idx BEFORE INSERT OR UPDATE ON table FOR EACH ROW EXECUTE PROCEDURE update_table_tsearch_idx();

8. Test searchable column:

SELECT * FROM table t WHERE t.tsearch_idx @@ to_tsquery('word1 & word2 & word3');
SELECT t.tsearch_idx::text FROM table t WHERE t.id = ?;

9. For more information see:

http://www.postgresql.org/docs/9.4/static/textsearch-configuration.html
https://www.postgresql.org/docs/9.4/static/textsearch.html