Implementing Full-Text Search
1. Understanding tsvector Type
SELECT 'The quick brown fox'::tsvector;
SELECT to_tsvector('english', 'The quick brown foxes jumped');
-- 'brown':3 'fox':4 'jump':5 'quick':2
2. Understanding tsquery Type
SELECT 'fox & jump'::tsquery;
SELECT to_tsquery('english', 'jumping & !lazy');
3. Creating tsvector Column
ALTER TABLE articles ADD COLUMN tsv tsvector
GENERATED ALWAYS AS (to_tsvector('english', coalesce(title,'') || ' ' || coalesce(body,''))) STORED;
4. Using to_tsvector Function
SELECT to_tsvector('english', 'PostgreSQL full-text search');
5. Using to_tsquery Function
SELECT to_tsquery('english', 'postgres & search');
SELECT to_tsquery('english', 'post:*'); -- prefix match
6. Using plainto_tsquery Function
SELECT plainto_tsquery('english', 'quick brown fox'); -- 'quick' & 'brown' & 'fox'
7. Using phraseto_tsquery Function
SELECT phraseto_tsquery('english', 'quick brown fox'); -- 'quick' <-> 'brown' <-> 'fox'
8. Using websearch_to_tsquery Function
SELECT websearch_to_tsquery('english',
'"quick brown" -lazy OR dog');
| Parser | Use |
|---|---|
| to_tsquery | Strict syntax (&, |, !) |
| plainto_tsquery | Words AND'ed |
| phraseto_tsquery | Phrase with <-> |
| websearch_to_tsquery | Google-style "..", OR, - |
9. Using Match Operator
SELECT id, title FROM articles
WHERE tsv @@ websearch_to_tsquery('english', 'postgres "full text"');
10. Creating GIN Index
CREATE INDEX articles_tsv_gin ON articles USING gin (tsv);
11. Using GiST Index
CREATE INDEX articles_tsv_gist ON articles USING gist (tsv);
| Index | Best For |
|---|---|
| GIN | Static-ish data, lots of reads |
| GiST | Mixed read/write workloads |
12. Ranking Search Results
SELECT id, title,
ts_rank(tsv, q) AS rank,
ts_rank_cd(tsv, q) AS rank_cd
FROM articles, websearch_to_tsquery('english','postgres') q
WHERE tsv @@ q ORDER BY rank DESC LIMIT 20;
13. Highlighting Results
SELECT ts_headline('english', body, q,
'StartSel=<b>,StopSel=</b>,MaxFragments=2')
FROM articles, websearch_to_tsquery('english','postgres') q
WHERE tsv @@ q;
14. Using Language Configurations
SELECT cfgname FROM pg_ts_config;
SELECT to_tsvector('spanish', 'corriendo rápido');
15. Creating Custom Text Search Configuration
CREATE TEXT SEARCH CONFIGURATION my_en (COPY = english);
ALTER TEXT SEARCH CONFIGURATION my_en
ALTER MAPPING FOR asciiword, word WITH unaccent, english_stem;