ParadeDB pg_search
What it is
ParadeDB pg_search adds BM25-ranked full-text search and faceted analytics directly to PostgreSQL. The index stays beside the source table, so application writes do not need a separate search synchronization pipeline.
What it provides
- BM25 relevance ranking across multiple fields
- Tokenizers, fuzzy matching, phrase queries, highlighting, and facets
- Search indexes maintained with the PostgreSQL data they cover
Use it for product catalogs, documentation search, support tickets, log exploration, faceted navigation, or hybrid lexical-and-vector retrieval.
Use it with Rent
extension pg_search {
name = "pg_search"
}The RSL declaration makes installation and migration intent part of the reviewed application schema. Register the typed pack at runtime to call its APIs:
let search = extensions.register_pack::<PgSearch>()?;
let index = Bm25Index::new(
&search,
"posts_search",
["id", "title", "body"],
"id",
)?
.fast_text_field("title")?;
let migration_operation = index.operation("public", "posts")?;
let query = search.search(
post::body(),
"rust database toolkit",
);
let posts = client
.post()
.where_raw(query.predicate())
.order_by_expression_desc(query.rank(post::id()))
.limit(20)
.all()
.await?;
let highlighted_body = query.highlight();
let title_facets = query.facet(
serde_json::json!({"terms": {"field": "title"}}),
);Text fields used for facets or sorting must be stored as fast fields. fast_text_field validates that the field is included in the index and emits ParadeDB's text_fields configuration for the migration.
Rent's ParadeDB profile verifies the generated index operation against an image that contains pg_search.
Run the application
cargo run -p rent --example extension_07_pg_searchSet DATABASE_URL to a disposable ParadeDB server whose role can create databases. The application creates
a BM25 index through Rent's migration API, inserts posts about databases and cooking, and searches for Rust.
It checks the matching post, a positive relevance score, the highlighted body, and the title facet. It also
checks an empty result and that hostile search text cannot escape into another SQL statement. The isolated
database is removed afterward.
Treat highlighted snippets as untrusted content when rendering them in HTML. Search ranking is not a
stable pagination key by itself; add a unique tie-breaker when paginating equally ranked results.
Its standalone extension declaration is crates/rent/examples/extension_07_pg_search/schema.rsl.