Tsearch2
Uit Yapf
Sinds versie 8.3 is de Tsearch functie onderdeel geworden van PostgreSQL zelf. Hiermee zijn ook een aantal benamingen veranderd maar daar dat kun je terugvinden in de handleiding.
Inhoud |
De basis
Tsearch werkt met twee fundamentele zaken; een vector en een query.
- Een vector is een tekst die is omgezet naar een serie woorden met wat extra informatie over elk woord.
- Een query is en presentatie van datgene waarop gezocht wordt. Dit kan ook logica bevatten zoals and,or, not en haakjes om de prioriteit aan te geven.
Het zoeken zelf gebeurt met de @@ operator, die een vector kan vergelijken met een query, of omgekeerd, maar altijd een vector met een query.
Eenvoudig Zoeken
Een simpel voorbeeld van een zoekopdracht is dit:
SELECT 'a fat cat sat on a mat and ate a fat rat'::tsvector @@ 'cat & rat'::tsquery;
Dit vergelijkt een vector met een query. De vector wordt gemaakt door een string te typecasten naar een tsvector en de query wordt gemaakt door een string om te zetten naar een tsquery. Samen met de @@ operator leveren ze als uitkomst true, omdat zowel cat als fat in de brontekst staan.
In plaats van casten kun je ook functies aanroepen die teksten omzetten naar vectors of queries:
SELECT to_tsvector('fat cats ate fat rats') @@ to_tsquery('fat & rat');
Deze geeft false, omdat rat niet hetzelfde is als rats. == Complexer zoeken
Relevantie en ranking
Een van de belangrijkste aspecten aan een zoekfunctie is het kunnen aangeven welk resultaat het beste past bij wat er gezocht is. Tsearch heeft hier een simpele functie voor: ts_rank_cd().
SELECT ts_rank_cd(to_tsvector('dutch', 'Nederland') ,to_tsquery('nederlands')) AS ranking;
Dit levert een getal tussen 0 en 1 op, waarbij '1' de beste match is.
Resultaat voorbeelden
Een van de grote voordelen van Tsearch is dat het functies bevat om relevante stukjes uit de doorzochte data te plukken en de gevonden woorden te markeren.
ts_headline([ config regconfig, ] document text, query tsquery [, options text ]) returns text
Taalafhankelijkheid
PostgreSQL kent standaard een aantal talen en deelt daarop ook punten uit per woord. Een woord kan in het Nederlands veel belangrijker zijn dan in het Engels.
Het doorvoeren van de taalafhankelijkheid is eenvoudig, de to_tsvector en to_tsquery functies krijgen twee paramaters, waarbij de eerste te naam van de taal is en de tweede de originele parameter.
Implementeren in een tabel
Om Tsearch te implementeren heb je twee keuzes, je kunt een nieuwe kolom maken en daarin de vectors opslaan, of je kunt een GIN index maken.
Een aparte kolom
Maak een nieuwe kolom, en vul die met behulp van een trigger met de to_tsvector() van de kolom(men) die je wilt doorzoeken. Bij het zoeken kun je rechtstreeks de inhoud van de nieuw kolom aanspreken als vector.
Indexes
Een eenvoudigere oplossing is een GIN index:
CREATE INDEX pgweb_idx ON pgweb USING gin(to_tsvector('english', body));
Dit indexeert de body kolom van de pgweb tabel in het Engels, en noemt die index pgweb_idx. Wanneer je in de de query een to_tsvector('english',body) opvraagt dan zal de database deze index gebruiken.