Full-Text Search with Ranking
PostgreSQL full-text search using tsvector, tsquery, and ts_rank with trigram similarity for fuzzy matching.
-- Add search vector column
ALTER TABLE articles ADD COLUMN search_vector tsvector;
-- Populate and keep in sync
UPDATE articles SET search_vector =
setweight(to_tsvector('english', coalesce(title, '')), 'A') ||
setweight(to_tsvector('english', coalesce(body, '')), 'B');
-- Create GIN index for fast lookups
CREATE INDEX idx_articles_search ON articles USING GIN (search_vector);
-- Auto-update trigger
CREATE FUNCTION articles_search_trigger() RETURNS trigger AS $$
BEGIN
NEW.search_vector :=
setweight(to_tsvector('english', coalesce(NEW.title, '')), 'A') ||
setweight(to_tsvector('english', coalesce(NEW.body, '')), 'B');
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER trg_articles_search
BEFORE INSERT OR UPDATE ON articles
FOR EACH ROW EXECUTE FUNCTION articles_search_trigger();
-- Search with ranking
SELECT id, title,
ts_rank(search_vector, query) AS rank
FROM articles,
plainto_tsquery('english', 'react hooks tutorial') AS query
WHERE search_vector @@ query
ORDER BY rank DESC
LIMIT 20;Sponsored
Typesense — Lightning-fast search engine
Use Cases
- Site search engines
- Document search
- Blog content discovery
Tags
Related Snippets
Similar patterns you can reuse in the same workflow.
Keyset Pagination vs Offset
Efficient keyset (cursor) pagination pattern compared to traditional OFFSET for large datasets in PostgreSQL.
UPSERT with ON CONFLICT
Insert or update rows atomically using PostgreSQL ON CONFLICT clause with partial indexes and conditions.
Window Functions with RANK and LAG
Use window functions to rank rows, calculate running totals, and compare with previous rows without self-joins.
JSON Aggregation and Querying
Aggregate related rows into JSON arrays and query JSONB columns with PostgreSQL native JSON operators.