This document explains how to use the pg_search gem with ParadeDB's pg_search PostgreSQL extension for BM25-based full-text search.
- Install the ParadeDB pg_search PostgreSQL extension in your database
- Use pg_search gem version 2.3.7 or later with ParadeDB support
In your Rails initializer (e.g., config/initializers/pg_search.rb):
PgSearch.multisearch_options = {
using: :paradedb
}Generate and run the migration to set up ParadeDB:
rails generate pg_search:migration:paradedb
rails db:migrateThis migration will:
- Install the pg_search PostgreSQL extension
- Create a BM25 index on the pg_search_documents table
# Perform a multisearch using ParadeDB's BM25 algorithm
results = PgSearch.multisearch("red shoes")
# Results are automatically ranked by BM25 score
results.each do |document|
puts "#{document.searchable_type} ##{document.searchable_id}"
puts "Content: #{document.content}"
end# Configure ParadeDB with query options
PgSearch.multisearch_options = {
using: {
paradedb: {
# Phrase search - finds exact phrases
query_type: :phrase
}
}
}
# Search for an exact phrase
PgSearch.multisearch("red running shoes")
# Prefix search - finds words starting with prefix
PgSearch.multisearch_options = {
using: {
paradedb: {
query_type: :prefix
}
}
}
PgSearch.multisearch("sho") # Finds: shoes, shopping, etc.
# Fuzzy search - finds similar words
PgSearch.multisearch_options = {
using: {
paradedb: {
query_type: :fuzzy,
fuzzy_distance: 2 # Allow up to 2 character differences
}
}
}
PgSearch.multisearch("sheos") # Finds: shoesYou can also use ParadeDB for model-specific searches:
class Product < ApplicationRecord
include PgSearch::Model
pg_search_scope :search_products,
against: [:name, :description],
using: {
paradedb: {
key_field: 'id' # Specify the primary key field
}
}
end
# Use it
products = Product.search_products("laptop")ParadeDB results are automatically ordered by BM25 score. You can access the rank:
results = PgSearch.multisearch("shoes").with_pg_search_rank
results.each do |result|
puts "Score: #{result.pg_search_rank}"
puts "Result: #{result.searchable}"
endThe ParadeDB migration creates a BM25 index with this structure:
CREATE INDEX pg_search_documents_bm25_idx
ON pg_search_documents
USING bm25 (searchable_id, searchable_type, content)
WITH (key_field='searchable_id');The key_field parameter is crucial as it's used by ParadeDB's score() function for ranking.
-
BM25 vs TSearch: ParadeDB's BM25 algorithm often provides better relevance ranking than PostgreSQL's built-in TSearch, especially for longer documents.
-
Index Size: BM25 indexes can be larger than TSearch indexes but provide faster query performance.
-
Query Syntax: ParadeDB supports a rich query syntax including wildcards, fuzzy matching, and phrase queries.
- ParadeDB features are only available when the pg_search PostgreSQL extension is installed
- Some advanced TSearch features (like language-specific stemming) may work differently with ParadeDB
- The multisearch table must have a numeric key field for scoring to work properly
If you encounter errors:
-
Ensure the pg_search PostgreSQL extension is installed:
CREATE EXTENSION IF NOT EXISTS pg_search;
-
Verify the BM25 index exists:
\di pg_search_documents_bm25_idx
-
Check that your queries are properly escaped (single quotes are automatically handled by the gem)