text or citext column (or a text-producing expression) for TINQL search, including phrases, proximity, and spans. Documents and queries are analyzed with the same tokenization pipeline.
Each TIN index covers one text source. Multi-column USING tin (…) indexes are not supported. To search several columns, create one TIN index per column and combine ==> predicates. tin.score(ctid) combines relevance across those columns.
Partial and expression indexes
Partial and expression TIN indexes work like other Postgres index types:(data->>'title') ==> … uses the expression index, and a plain title ==> … does not. A partial index is used only when Postgres can prove the query implies its WHERE predicate (for example WHERE active AND body ==> …).
Index options (WITH)
Scoring
Scoring options are read at query time, so
ALTER INDEX ... SET takes effect on the next scored query without a rebuild. k1 and b can also be overridden for a single query with tin.score(ctid, k1 => …, b => …). tin.score_inspect shows which terms a query would score after stop words and dense-term elision are applied.
Tokenization
Defaults fold case and accents, split over-long tokens on grapheme boundaries, and emit emoji as searchable terms. Indexing and query analysis use the same pipeline, so
==> searches agree with what the index stored.
tin.tokenize to inspect the pipeline. Named arguments match the index options and use the same defaults:
wi-fi becomes the phrase "wi fi"). Fuzzy (term~N) requires a single token after tokenization.
Changing tokenization options on a populated index does not re-tokenize stored rows. Run REINDEX to apply the new policy to them.
Segments
A TIN index is stored as segments. The segment count sets how many parallel workers a build and a query can use, and background maintenance folds new writes into segments over time.
Changes to these options take effect on the next maintenance pass, except
initial_segment_count, which is read only at build.

