@@, plainto_tsquery, phraseto_tsquery, websearch_to_tsquery. — Cracked Java
// PostgreSQL · Full-Text Search
MidCodingTrick

@@, plainto_tsquery, phraseto_tsquery, websearch_to_tsquery.

to_tsquery is powerful but unforgiving of raw user input; the *to_tsquery family exists to turn human-typed text into a valid tsquery safely. Picking the right constructor is mostly about what the input looks like and how much boolean control you want.

@@ — the match operator

@@ returns boolean: does the tsvector satisfy the tsquery? Everything below produces the right-hand tsquery; @@ does the comparison.

WHERE search_vec @@ websearch_to_tsquery('english', :userInput)

to_tsquery — full operator syntax, throws on bad input

You write the operators yourself: & | ! <->. It's precise but raises an error on unbalanced or malformed input, so never feed it raw user text.

to_tsquery('english', 'fox & (quick | brown) & !slow')

plainto_tsquery — plain words, all ANDed

Takes arbitrary text, ignores punctuation/operators, and joins the resulting lexemes with &. Safe for user input, but you can't express OR or phrases.

plainto_tsquery('english', 'quick brown fox')   -- 'quick' & 'brown' & 'fox'

phraseto_tsquery — words must be adjacent

Like plainto_tsquery but joins lexemes with <-> so they must appear in order, adjacent. This is how you do exact-phrase search.

phraseto_tsquery('english', 'quick brown fox')   -- 'quick' <-> 'brown' <-> 'fox'

websearch_to_tsquery — Google-style syntax

Accepts the syntax users already know: unquoted words are ANDed, "quoted phrases" become <->, or becomes |, and a leading - becomes !. Never errors on bad input. This is the right default for a search box.

websearch_to_tsquery('english', 'postgres "full text" or sql -mysql');
-- 'postgr' & ('full' <-> 'text') & 'sql' & !'mysql'

Mark your status