tsvector and tsquery
PostgreSQL ships a complete full-text search engine. tsvector stores normalised, stemmed lexemes; tsquery represents the search query. The match operator @@ tests whether a tsvector matches a tsquery. With a GIN index, this is millisecond search across millions of documents.
The pieces
to_tsvector('english', text)— convert text to a normalised vector.to_tsquery('english', 'postgres & performance')— parse a query.plainto_tsquery/websearch_to_tsquery— friendlier query parsers.ts_rank/ts_rank_cd— relevance scoring.ts_headline— generate a snippet with matched terms highlighted.
Storing the tsvector
For performance, materialise the tsvector as a generated column and index it with GIN. You compute the conversion once on write and reuse it on every search.