PostgreSQL + Full Text Search
Sziasztok!
Egy ideje már játszadozok a PostgreSQL-lel, most jutottam el odáig, hogy full text keresést is használnék. Egyelőre csak tapogatózom, az alábbi kérdéseim merültek fel:
1. Melyik a legjobb megoldás a megvalósításra (sebesség, egyszerűség tekintetében)? A beépített FTS, vagy a "külső" megoldások? Olvasgattam a Solr-t és a Sphinxről, nekem jobban tetszik, hogy "házon belül" marad a megoldás, nem kell külön szoftvert telepítenem a szerverre. Milyen előnyei lehetnek az utóbbiaknak?
2. Magyar nyelv esetén mennyire működőképes a dolog? Értem ez alatt a stop szavakat és a szótövezést. Kereséskor a szótövezés automatikusan működik vagy úgy kell szerkeszteni az SQL lekérdezést? Mi a helyzet az elválasztással?
3. A sorba rendezés része nem teljesen tiszta, arról valamit tudnátok mondani pár szóban? Ha valami precedenciát szeretnék, azt ki lehet kényszeríteni. Itt ilyenre gondolok, hogy van egy topic táblám title és body mezővel, akkor a title-ben lévő találatok előbb helyezkedjenek el, mint a body.
Köszi,
dave
■ Egy ideje már játszadozok a PostgreSQL-lel, most jutottam el odáig, hogy full text keresést is használnék. Egyelőre csak tapogatózom, az alábbi kérdéseim merültek fel:
1. Melyik a legjobb megoldás a megvalósításra (sebesség, egyszerűség tekintetében)? A beépített FTS, vagy a "külső" megoldások? Olvasgattam a Solr-t és a Sphinxről, nekem jobban tetszik, hogy "házon belül" marad a megoldás, nem kell külön szoftvert telepítenem a szerverre. Milyen előnyei lehetnek az utóbbiaknak?
2. Magyar nyelv esetén mennyire működőképes a dolog? Értem ez alatt a stop szavakat és a szótövezést. Kereséskor a szótövezés automatikusan működik vagy úgy kell szerkeszteni az SQL lekérdezést? Mi a helyzet az elválasztással?
3. A sorba rendezés része nem teljesen tiszta, arról valamit tudnátok mondani pár szóban? Ha valami precedenciát szeretnék, azt ki lehet kényszeríteni. Itt ilyenre gondolok, hogy van egy topic táblám title és body mezővel, akkor a title-ben lévő találatok előbb helyezkedjenek el, mint a body.
Köszi,
dave
"use-case"
- én csak a Postgres saját rendszerét alkalmaztam - a többiről sejtelmem sincs, de ha azokat kiterjesztésként (extension) kell telepíteni, akkor annyira rosszak nem lehetnek...
- a szótövezést megoldja magától az FTS; szótagolás alatt nem tudom mit értesz, de próbaképpen a "képvisel", illetve "képviselt" lekérdezésekre is kiadott olyan találatokat, melyekben szerepel a képviselet szó; ha a "hotelek"-re keresek, akkor pedig az összes "hotel" is szerepel az eredmények között
- SQL-ben rendezni az
Alább egy kis tapasztalat/összefoglaló, hogy én mire-hogyan használtam fel...ORDER BY
záradékkal lehet; a MySQL-lel ellentétben a Postgres nem rendez automatikusan a FULLTEXT-es keresés relevanciájára - arra külön "kérni" kell;ilyen relevancia adatot a
ts_rank_cd()
függvény szolgáltatElőszó: ezt az egészet még régebben csináltam, 8.3, 8.4 verzióval; azóta remélhetőleg fejlődött a technika/technológia. Továbbá bizonyos miértek a feledés homályába vesznek... :-/
A rendszerben előtte sima toldozott-foltozott
LIKE
kifejezésekkel volt megoldva a keresés, de a félreírt adatok, ronda helyesírás s (előbbiek által is) a rossz keresési eredmények miatt szükségessé vált egy okosabb megoldás.Nem utolsó sorban ahogy' növekedett az adatbázis, úgy vált egyre használhatalanabbá a keresés funkció.
Részemről csak a hivatalos dokumentáció alapján dolgoztam, átvettem annak ajánlásait:
FULLTEXT kereséshez elég csak a to_tsvector() és to_tsquery() függvényeket kombinálni a @@ operátorral.
A függvények első paramétere a FULLTEXT keresés nyelve, második a "kezelni" kívánt szöveg (TEXT):
Ezen mező automatikus frissítését érdemes TRIGGER-rel megoldani:
- a magyar szótövezés nem ismeri sem az angol, sem más nyelvek többesszámát:
ennek hozadéka, hogy a magyar szabályok alapján megmarad a hotels szó, míg az angol leszótövezi s így mindkét szó letárolásra kerül,
- az előbbi pont "kártékony" hatása, hogy a ts_rank()/ts_rank_cd()-nél is meg kell ismételni az összefűzést - illetve nem szabad elfelejteni: egy ideig így hibás volt a program és az eredmények között szerepelt a keresett dolog, csak a
- rendezéshez én továbbra is használom, illetve ajánlom a
kitételt, mivel nem mindig kap(ott) maximális pontszámot a keresett név. ennek gyorsítására kapott egy saját indexet is a mező: - mivel nálunk probléma [volt], hogy az adatok felvitelekor nem mindeki ír helyesen és/vagy elrontja az ékezetes betűket, így a FULLTEXT mező generálásához még hozzátettem a nev mező ékezetek nélküli változatát is:
- aztán volt-lett-jött egy olyan probléma, hogy a nem alfanumerikus karaktereket (kötőjel, vessző stb.!) tartalmazó rekordok nem jöttek elő keresésre, illetve "aszem" néha félreértette azokat a
- alapértelmezésben a @@ keresés nem keres a paraméterben megadott kezdetű szavakra:
így, a fenti pontok tapasztalatai után a következőképp' torzult az eredeti TRIGGER függvény:ez úgy jött elő, hogy a "hotels" kifejezésre tényleg csak a "hotels" szót tartalmazó találatok jelentek meg. megoldás: a to_tsquery() és to_tsvector() függvényhívásokhoz hozzáfűzni (
||
) az angol szabályok szerinti eredményt, lekérdezést is:és ha a "hotels"-re keresésnél a hotels-t tartalmazó találatok jobb pontszámot kapnak
ts_rank_cd()
pontozás mássága miatt az eredménylista végére került :-/to_tsvector()
. erre a válaszom az alábbi reguláris kifejezés lett:a
WHERE nev_ft @@ to_tsquery('hungarian', 'hotelek')
lekérdezés nem fogja kiadni a 'hoteljofajta' nevűt. megoldás:a keresési lekérdezés szavainak végére "csak" oda kell biggyeszteni a
:*
szöveget és már működik is:Köszi a kimerítő választ. Az
Az elválasztás alatt kb. azt értem, ha a mezőben a kép-viselt szó szerepel, akkor hogy lehetne megoldani, hogy a képvisel szóra találat legyen
Ami furcsa volt még, hogy pl. a
intelligencs rendszerek...
valószínűleg a szótövezős/szótár rész túl okos és tartalmazza ezt szóösszetételt. szerintem biztos még van egypár ilyen furaság :-/
egyik ötlet, hogy kijavítod a szótárt és/vagy szótövező algoritmust, vagy használod a FULLTEXT angol részét is: