Full-textové vyhledávání v PostgreSQL Július Štroffek Revenue Product Engineer Sun Microsystems 1
Agenda • Historie • Cíle full-textového vyhledávání • Databázové objekty pro Full-Text Search (FTS) > Datové typy, funkce a operátory > Parsery, šablony, slovníky, konfigurace
• Zpracování prohledávaného textu a dotazů • Vyhledávání a ohodnocování (ranking) • Indexy pro Full-Text Search 2
Historie • 2000 – 2005 OpenFTS – Open Full Text Search > XWare Team - Oleg Bartunov, Teodor Sigaev, Daniel
Wickstrom > Založen na PostgreSQL, TSearch, TSearch2 > PostgreSQL využívá pouze pro ukládání dat
• 2003 – 2007 TSearch2 contrib module > Přesun funkcionality z OpenFTS
• 2008 – > Od verze PostgreSQL 8.3 je FTS součást jádra DB
3
Cíle full-textového vyhledávaní • Najít dokumenty obsahující zadaná slova • Efektivně vyhledávat ve velkém množství dokumentů • Zaměřit se pouze na “důležitá” slova • Považovat různé tvary stejného slova za slova stejná • Umět pracovat s více jazyky • Uživatelská konfigurovatelnost
4
Databázové objekty FTS • Full-text search poskytuje následující databázové objekty > Parsery – transformace vstupního textu na posloupnost > > > > >
tokenů; \dFp(+) Šablony – slovníkové schéma/formát; \dFt(+) Slovníky – seznam “dvojic” slov pro nahrazení; slova, která se ignorují – tzv. stop words; \dFd(+) Konfigurace – parser a posloupnost slovníků; \dF(+) Datové typy – tsvector, tsquery Funkce, operátory
• Contrib modul pro kompatibilitu s verzí 8.2 5
Full-Text Search - schéma
6
Datový typ tsvector I • • • • • •
Reprezentuje prohledávaný dokument Seznam slov/tokenů vyskytujících se v dokumentu Může obsahovat pozice slov Řazení slov podle délky slova a abecedně Lepší je použít normalizace dle slovníků Přetypování pomocí ::tsvector
7
Datový typ tsvector II • Funkce to_tsvector() - normalizace slov dle slovníků • setweight(tsvector, “char”) > Nastavení váhy pro všechny prvky
• || - sjednocení tsvector-ů • ... viz. manuál PostgreSQL 8.3
8
Ukázka nastavení vah select setweight( to_tsvector('Book Title'), 'A' ) || setweight( to_tsvector('This is a book text'), 'B' );
9
Datový typ tsquery • Reprezentuje dotaz nad tsvector-mi • Použití logických spojek a negace, &, |, ! • Nutná normalizace dle stejných slovníků jako prohledávaný text • Přetypování pomocí ::tsquery • Funkce to_tsquery() > Vytvoření tsquery s použitím logický spojek &,|,! > Normalizace slov dle slovníků
• Logické operátory &&, ||, !! 10
Datové typy
Ukázky
11
Funkce a operátory I Vyhledávání
• Operátory @@, @@@ > S Výsledkem je pravdivostná hodnota jestli dokument vyhovuje zadanému dotazu > Použití @@@ je nutné pro dotaz využívající GIN index a mající podmínku na ranking • ts_headline() > Zobrazení vyhledávané části v textu
12
Funkce a operátory II Ohodnocování (ranking)
• ts_rank(weights[], tsvector, tsquery, normalization) > Ohodnocení splněnosti dotazu v závislosti na vzdálenosti hledaných slov v dokumentu • ts_rank_cd() > Používá jinou funkci – tzv. cover density
13
Funkce a operátory
Ukázky
14
Podpora národních jazyků • Pro různé jazyky musí existovat různé konfigurace zpracování textu v daném jazyce • Všechny funkce zpracovávající texty pro FTS mají volitelně první parameter – konfiguraci FTS • Pokud není konfigurace uvedena, použije se výchozí – t.j. get_current_ts_config() • Parameter - set/show default_text_search_config • Inicializace dle lc_ctype při initdb, pokud konfigurace s daným jménem existuje 15
Parser • Standardně dostupný je pouze výchozí • Dělení dokumentu na tokeny několika typů > asciiword, word, numword, asciihword, hword,
numhword, hword_asciipart, hword_part, hword_numpart, email, protocol, url, host, url_path, file, sfloat, float, int, uint, version, tag, entity, blank
• Znaky slova jsou definovány dle nastavení lc_locale na serveru
16
Parser - ladění • ts_token_type('default') > Vrátí seznam typů tokenů pro daný parser
• ts_parse('default', Document) > Vypíše seznam tokenů a odpovídajících řetězců po
zpracování uvedeného dokumentu daným parserem
17
Parser - ladění
Ukázky
18
Slovníky • Vyřazují často se vyskytující slova (tokeny) > Mezerové znaky, určité členy, předložky > Pomocné slovesa
• Normalizovat tvar slov > > > >
Podst. jména - první pád, slovesa – neurčitek Zaokrouhlení čísel Úprava url na zhodný tvar Nahrazení synonymem
• Výstupem jednoho slova může být i několik slov, tzv. lexémů 19
Vytvoření slovníku – šablony I • pg_catalog.simple > Obsahuje pouze “stop words”
• pg_catalog.synonym > Obsahuje dvojice slov pro nahrazení (nejen synonyma)
• pg_catalog.thesaurus > Zobecnění synonym pro celé fráze > Musí obsahovat právě jeden podslovník
20
Vytvoření slovníku – šablony II • pg_catalog.ispell > Konverze z pravopisního slovníku > Pravidla pro generování různých tvarů jsou použita pro
úpravu na základní tvar (kořen) > Problém s úpravou nepravidelných slov – chybí vazba na základní tvar
• pg_catalog.snowball > Použit pro podporu všech současně podporovaných
jazyků – danish, dutch, english, finnish, french, german, hungarian, italian, norwegian, portuguese, romanian, russian, spanish, swedish, turkish > Viz http://en.wikipedia.org/wiki/Stemming 21
Slovníky - ladění • ts_lexize(dictionary, token) > Zobrazí výstup slovníku při zpracování daného tokenu postgres=# select * from ts_lexize('english_stem', 'cats'); ts_lexize ----------{cat} (1 row)
22
Konfigurace • Určuje parser a slovníky, kterými se zpracovávají příslušné dokumenty • Specifikuje mappingy na posloupnosti slovníků pro různé typy tokenů • Viz \dF+ english
23
Full-Text Search - schéma
24
Ukázka konfigurace postgres=# \dF+ english Text search configuration "pg_catalog.english" Parser: "pg_catalog.default" Token | Dictionaries -----------------+-------------asciihword | english_stem asciiword | english_stem email | simple hword | english_stem hword_numpart | simple hword_part | english_stem int | simple ... version | simple word | english_stem 25
Vytvoření slovníku a konfigurace
Ukázky
26
Indexování • GiST – Generalized Search Tree > Horší škálovatelnost pro velký počet dokumentů
• GIN - Generalized Inverted Index > Indexuje dvojice (lexem, seznam dokumentů) > Dobrá škálovatelnost i pro velký počet dokumentů
CREATE INDEX INDEX_NAME ON TABLE_NAME USING GIN/GIST (COLUMN_NAME);
27
Otázky, dotazy, připomínky...
28
Ďekuji.
29
Full-textové vyhledávání v PostgreSQL Július Štroffek
[email protected]
30
GiST – Generalized Search Tree • Pro každý dokument je alokováno bitové pole stejné délky • Každé slovo vyskytující se v dokumentu je hashováno do tohoto bitového pole • Více slov = stejný bit • Při selekci přes index je nutná kontrola (dělá se automaticky) • Viz http://en.wikipedia.org/wiki/GiST
31
GIN - Generalized Inverted Index • Indexuje dvojice (lexem, seznam dokumentů) • Pro operátor vyhledání @@ již výsledek index scanu není kontrolován • Neukládá informaci o vahách a tudíž při uvedení podmínky používající váhy nutno číst i datové bloky • Pro operátor @@@ je nutno výsledek index scanu překontrolovat (dělá se automaticky) – nutno použít pokud je použita podmínka na ranking ve where klauzuli!!! 32