Skip to content

pg_fts

pg_fts : Full-text search with BM25 and BM25F ranking

Overview

IDExtensionPackageVersionCategoryLicenseLanguage
2220
pg_fts
pg_fts
0.2.0
FTS
PostgreSQL
C
AttributeHas BinaryHas LibraryNeed LoadHas DDLRelocatableTrusted
--s-dtr
No
Yes
No
Yes
yes
yes
Relationships
See Also
pg_search
pg_textsearch
vchord_bm25
psql_bm25s
pg_bestmatch

Requires PostgreSQL 17 or newer; the control file marks the extension trusted and relocatable; RPM builds also provide an llvmjit subpackage.

Packages

TypeRepoVersionPG Major CompatibilityPackage PatternDependencies
EXT
PIGSTY
0.2.0
18
17
16
15
14
pg_fts-
RPM
PIGSTY
0.2.0
18
17
16
15
14
pg_fts_$v-
DEB
PIGSTY
0.2.0
18
17
16
15
14
postgresql-$v-pg-fts-
Linux / PGPG18PG17PG16PG15PG14
el8.x86_64
PIGSTY 0.2.0
PIGSTY 0.2.0
MISS
MISS
MISS
el8.aarch64
PIGSTY 0.2.0
PIGSTY 0.2.0
MISS
MISS
MISS
el9.x86_64
PIGSTY 0.2.0
PIGSTY 0.2.0
MISS
MISS
MISS
el9.aarch64
PIGSTY 0.2.0
PIGSTY 0.2.0
MISS
MISS
MISS
el10.x86_64
PIGSTY 0.2.0
PIGSTY 0.2.0
MISS
MISS
MISS
el10.aarch64
PIGSTY 0.2.0
PIGSTY 0.2.0
MISS
MISS
MISS
d12.x86_64
PIGSTY 0.2.0
PIGSTY 0.2.0
MISS
MISS
MISS
d12.aarch64
PIGSTY 0.2.0
PIGSTY 0.2.0
MISS
MISS
MISS
d13.x86_64
PIGSTY 0.2.0
PIGSTY 0.2.0
MISS
MISS
MISS
d13.aarch64
PIGSTY 0.2.0
PIGSTY 0.2.0
MISS
MISS
MISS
u22.x86_64
PIGSTY 0.2.0
PIGSTY 0.2.0
MISS
MISS
MISS
u22.aarch64
PIGSTY 0.2.0
PIGSTY 0.2.0
MISS
MISS
MISS
u24.x86_64
PIGSTY 0.2.0
PIGSTY 0.2.0
MISS
MISS
MISS
u24.aarch64
PIGSTY 0.2.0
PIGSTY 0.2.0
MISS
MISS
MISS
u26.x86_64
PIGSTY 0.2.0
PIGSTY 0.2.0
MISS
MISS
MISS
u26.aarch64
PIGSTY 0.2.0
PIGSTY 0.2.0
MISS
MISS
MISS
PackageVersionOSORGSIZEFile URL
pg_fts_180.2.0el8.x86_64pigsty113.6 KiBpg_fts_18-0.2.0-1PIGSTY.el8.x86_64.rpm
pg_fts_180.2.0el8.aarch64pigsty109.9 KiBpg_fts_18-0.2.0-1PIGSTY.el8.aarch64.rpm
pg_fts_180.2.0el9.x86_64pigsty88.3 KiBpg_fts_18-0.2.0-1PIGSTY.el9.x86_64.rpm
pg_fts_180.2.0el9.aarch64pigsty88.3 KiBpg_fts_18-0.2.0-1PIGSTY.el9.aarch64.rpm
pg_fts_180.2.0el10.x86_64pigsty91.4 KiBpg_fts_18-0.2.0-1PIGSTY.el10.x86_64.rpm
pg_fts_180.2.0el10.aarch64pigsty90.3 KiBpg_fts_18-0.2.0-1PIGSTY.el10.aarch64.rpm
postgresql-18-pg-fts0.2.0d12.x86_64pigsty265.4 KiBpostgresql-18-pg-fts_0.2.0-1PIGSTY~bookworm_amd64.deb
postgresql-18-pg-fts0.2.0d12.aarch64pigsty258.2 KiBpostgresql-18-pg-fts_0.2.0-1PIGSTY~bookworm_arm64.deb
postgresql-18-pg-fts0.2.0d13.x86_64pigsty266.9 KiBpostgresql-18-pg-fts_0.2.0-1PIGSTY~trixie_amd64.deb
postgresql-18-pg-fts0.2.0d13.aarch64pigsty260.3 KiBpostgresql-18-pg-fts_0.2.0-1PIGSTY~trixie_arm64.deb
postgresql-18-pg-fts0.2.0u22.x86_64pigsty271.9 KiBpostgresql-18-pg-fts_0.2.0-1PIGSTY~jammy_amd64.deb
postgresql-18-pg-fts0.2.0u22.aarch64pigsty268.8 KiBpostgresql-18-pg-fts_0.2.0-1PIGSTY~jammy_arm64.deb
postgresql-18-pg-fts0.2.0u24.x86_64pigsty256.4 KiBpostgresql-18-pg-fts_0.2.0-1PIGSTY~noble_amd64.deb
postgresql-18-pg-fts0.2.0u24.aarch64pigsty253.2 KiBpostgresql-18-pg-fts_0.2.0-1PIGSTY~noble_arm64.deb
postgresql-18-pg-fts0.2.0u26.x86_64pigsty256.5 KiBpostgresql-18-pg-fts_0.2.0-1PIGSTY~resolute_amd64.deb
postgresql-18-pg-fts0.2.0u26.aarch64pigsty252.6 KiBpostgresql-18-pg-fts_0.2.0-1PIGSTY~resolute_arm64.deb

Source

pig build pkg pg_fts;		# build rpm/deb

Install

Make sure PGDG and PIGSTY repo available:

pig repo add pgsql -u   # add both repo and update cache

Install this extension with pig:

pig install pg_fts;		# install via package name, for the active PG version

pig install pg_fts -v 18;   # install for PG 18
pig install pg_fts -v 17;   # install for PG 17

Create this extension with:

CREATE EXTENSION pg_fts;

Usage

Sources:

pg_fts provides BM25/BM25F full-text ranking through dedicated ftsdoc and ftsquery types and an fts inverted-index access method. It supports boolean, phrase, NEAR, prefix, fuzzy, and regular-expression terms while keeping corpus statistics in the index for relevance scoring. Version 0.2.0 requires PostgreSQL 17 or newer.

Create and Query an Index

CREATE EXTENSION pg_fts;

CREATE TABLE docs (
    id bigint PRIMARY KEY,
    body text NOT NULL
);

CREATE INDEX docs_fts
ON docs USING fts (to_ftsdoc('english', body));

Use the same text-search configuration for documents and ordinary query terms:

WITH q AS (
    SELECT to_ftsquery('english', 'postgres & "query planner" & index*') AS query
)
SELECT d.id,
       fts_snippet(d.body, q.query) AS excerpt
FROM docs AS d
CROSS JOIN q
WHERE to_ftsdoc('english', d.body) @@@ q.query
ORDER BY to_ftsdoc('english', d.body) <=> q.query
LIMIT 10;

@@@ matches, while ascending <=> distance orders rows by descending relevance and can drive an index ordering scan for top-k queries.

Query Language and API Index

  • to_ftsdoc([regconfig,] text) and to_ftsquery([regconfig,] text): analyze documents and parse queries.
  • quick brown, quick & brown, quick | brown, and !slow: implicit/explicit AND, OR, and NOT.
  • "quick brown", NEAR(...), term*, term~2, and /regular-expression/: phrase, proximity, prefix, fuzzy, and regex terms.
  • fts_bm25, fts_bm25_opts, and fts_bm25f: explicit BM25 scoring variants and multi-field scoring.
  • fts_index_stats(index) and fts_index_df(index, query): index-maintained document count, average length, vocabulary size, and term frequencies.
  • fts_highlight and fts_snippet: present matching text.
  • fts_search(index, query, k) and fts_count(index, query): index-native top-k and MVCC-aware count operations.
  • tsquery_to_ftsquery(tsquery): migration helper; it does not make pg_fts a transparent replacement for tsvector/GIN.

Maintenance and Version Caveats

SELECT fts_merge('docs_fts');
SELECT fts_vacuum('docs_fts');
  • Inserts enter an immediately matchable pending list, but ranked <=> and fts_search results cover merged segments. Run fts_merge() when newly inserted documents must participate in ranking immediately.
  • fts_vacuum() compacts segments and truncates reclaimable index pages; ordinary VACUUM also participates in pending-list and tombstone maintenance.
  • Version 0.2.0 renamed the access method from bm25 to fts. Indexes created by 0.1.0 with USING bm25 must be recreated.
  • If the library reports an on-disk format mismatch, follow its REINDEX hint rather than attempting to read the index with a different format version.
  • The access method is non-covering and does not provide parallel scans in this release. Provision the extension and index separately on logical-replication subscribers; indexes themselves are not logically replicated.
Last updated on