module
PgORM::FullTextSearch
Overview
Full-text search support using PostgreSQL's tsvector and tsquery.
This module provides a comprehensive interface to PostgreSQL's powerful full-text search capabilities, including:
- Basic text search with multiple columns
- Weighted search (prioritize certain columns)
- Ranked search (order by relevance)
- Phrase search (exact phrase matching)
- Proximity search (words within N positions)
- Prefix search (word prefix matching)
- Pre-computed tsvector columns (for production performance)
Basic Usage
# Simple search across multiple columns
Article.search("crystal programming", :title, :content)
# Weighted search (title more important than content)
Article.search_weighted("crystal", {
title: FullTextSearch::Weight::A, # Weight 1.0
content: FullTextSearch::Weight::B, # Weight 0.4
})
# Ranked search (ordered by relevance)
Article.search_ranked("crystal programming", :title, :content)
Advanced Usage
# Phrase search (exact phrase)
Article.search_phrase("crystal programming language", :content)
# Proximity search (words within 5 positions)
Article.search_proximity("crystal", "programming", 5, :content)
# Prefix search (matches crystal, crystalline, etc.)
Article.search_prefix("cryst", :title, :content)
Production Optimization
For better performance, use pre-computed tsvector columns:
-- Add tsvector column
ALTER TABLE articles ADD COLUMN search_vector tsvector;
-- Create GIN index
CREATE INDEX articles_search_idx ON articles USING GIN(search_vector);
-- Auto-update trigger
CREATE TRIGGER articles_search_update
BEFORE INSERT OR UPDATE ON articles
FOR EACH ROW EXECUTE FUNCTION
tsvector_update_trigger(search_vector, 'pg_catalog.english', title, content);
Then use the optimized search methods:
Article.search_vector("crystal programming", :search_vector)
Article.search_vector_ranked("crystal", :search_vector)
Defined in:
pg-orm/full_text_search.crInstance Method Summary
-
#search(query : String, columns : Array(String), config : String = "english") : Collection(self)
Performs full-text search using to_tsvector and to_tsquery
-
#search(query : String, *columns : Symbol, config : String = "english") : Collection(self)
Overload: Accepts Symbol columns
-
#search(query : String, *columns : String, config : String = "english") : Collection(self)
Overload: Accepts String columns
-
#search_phrase(phrase : String, columns : Array(String), config : String = "english") : Collection(self)
Performs phrase search (exact phrase matching)
-
#search_phrase(phrase : String, *columns : Symbol, config : String = "english") : Collection(self)
Overload: Accepts Symbol columns
-
#search_phrase(phrase : String, *columns : String, config : String = "english") : Collection(self)
Overload: Accepts String columns
-
#search_plain(text : String, columns : Array(String), config : String = "english") : Collection(self)
Performs plain text search (automatically converts to tsquery)
-
#search_plain(text : String, *columns : Symbol, config : String = "english") : Collection(self)
Overload: Accepts Symbol columns
-
#search_plain(text : String, *columns : String, config : String = "english") : Collection(self)
Overload: Accepts String columns
-
#search_prefix(prefix : String, columns : Array(String), config : String = "english") : Collection(self)
Performs prefix search
-
#search_prefix(prefix : String, *columns : Symbol, config : String = "english") : Collection(self)
Overload: Accepts Symbol columns
-
#search_prefix(prefix : String, *columns : String, config : String = "english") : Collection(self)
Overload: Accepts String columns
-
#search_proximity(word1 : String, word2 : String, distance : Int32, columns : Array(String), config : String = "english") : Collection(self)
Performs proximity search (words within N positions)
-
#search_proximity(word1 : String, word2 : String, distance : Int32, *columns : Symbol, config : String = "english") : Collection(self)
Overload: Accepts Symbol columns
-
#search_proximity(word1 : String, word2 : String, distance : Int32, *columns : String, config : String = "english") : Collection(self)
Overload: Accepts String columns
-
#search_ranked(query : String, columns : Array(String), config : String = "english", rank_normalization : Int32 | Nil = nil, rank_function : RankFunction = RankFunction::Rank) : Collection(self)
Performs full-text search and orders by relevance rank
-
#search_ranked(query : String, *columns : Symbol, config : String = "english", rank_normalization : Int32 | Nil = nil, rank_function : RankFunction = RankFunction::Rank) : Collection(self)
Overload: Accepts Symbol columns
-
#search_ranked(query : String, *columns : String, config : String = "english", rank_normalization : Int32 | Nil = nil, rank_function : RankFunction = RankFunction::Rank) : Collection(self)
Overload: Accepts String columns
-
#search_ranked_weighted(query : String, weighted_columns : Hash(String, Weight), config : String = "english", rank_normalization : Int32 | Nil = nil, rank_function : RankFunction = RankFunction::Rank) : Collection(self)
Performs full-text search with weighted columns and ranking
-
#search_ranked_weighted(query : String, weighted_columns : Hash(Symbol, Weight), config : String = "english", rank_normalization : Int32 | Nil = nil, rank_function : RankFunction = RankFunction::Rank) : Collection(self)
Overload: Accepts Symbol keys for weighted columns
-
#search_vector(query : String, vector_column : String, config : String = "english") : Collection(self)
Searches using a pre-computed tsvector column (recommended for production)
-
#search_vector(query : String, vector_column : Symbol, config : String = "english") : Collection(self)
Overload: Accepts Symbol for vector column
-
#search_vector_plain(text : String, vector_column : String, config : String = "english") : Collection(self)
Searches using a pre-computed tsvector column with plain text query
-
#search_vector_plain(text : String, vector_column : Symbol, config : String = "english") : Collection(self)
Overload: Accepts Symbol for vector column
-
#search_vector_ranked(query : String, vector_column : String, config : String = "english", rank_normalization : Int32 | Nil = nil, rank_function : RankFunction = RankFunction::Rank) : Collection(self)
Searches using a pre-computed tsvector column with ranking
-
#search_vector_ranked(query : String, vector_column : Symbol, config : String = "english", rank_normalization : Int32 | Nil = nil, rank_function : RankFunction = RankFunction::Rank) : Collection(self)
Overload: Accepts Symbol for vector column
-
#search_weighted(query : String, weighted_columns : Hash(String, Weight), config : String = "english") : Collection(self)
Performs full-text search with weighted columns
-
#search_weighted(query : String, weighted_columns : Hash(Symbol, Weight), config : String = "english") : Collection(self)
Overload: Accepts Symbol keys for weighted columns
Instance Method Detail
Performs full-text search using to_tsvector and to_tsquery
Article.search("crystal & programming", :title, :content)
Article.search("crystal | ruby", :title, config: "simple")
Article.search("cryst:*", :title) # Prefix matching
Article.search("crystal", ["title", "content"]) # Array of strings
Overload: Accepts Symbol columns
Overload: Accepts String columns
Performs phrase search (exact phrase matching)
Article.search_phrase("crystal programming language", ["content"])
Article.search_phrase("crystal programming", :title, :content)
Overload: Accepts Symbol columns
Overload: Accepts String columns
Performs plain text search (automatically converts to tsquery)
Article.search_plain("crystal programming", :title, :content)
Overload: Accepts Symbol columns
Overload: Accepts String columns
Performs prefix search
Article.search_prefix("cryst", :title, :content) # Matches crystal, crystalline, etc.
Overload: Accepts Symbol columns
Overload: Accepts String columns
Performs proximity search (words within N positions)
Article.search_proximity("crystal", "programming", 5, :content) # Within 5 words
Overload: Accepts Symbol columns
Overload: Accepts String columns
Performs full-text search and orders by relevance rank
Article.search_ranked("crystal programming", ["title", "content"])
Article.search_ranked("ruby", ["title", "content"], rank_normalization: 1)
Article.search_ranked("ruby", :title, :content, rank_function: RankFunction::RankCD)
Overload: Accepts Symbol columns
Overload: Accepts String columns
Performs full-text search with weighted columns and ranking
Article.search_ranked_weighted("crystal", {"title" => Weight::A, "content" => Weight::B})
Article.search_ranked_weighted("crystal", {title: Weight::A, content: Weight::B})
Overload: Accepts Symbol keys for weighted columns
Searches using a pre-computed tsvector column (recommended for production)
# Setup (run once):
# ALTER TABLE articles ADD COLUMN search_vector tsvector;
# CREATE INDEX articles_search_idx ON articles USING GIN(search_vector);
# CREATE TRIGGER articles_search_update BEFORE INSERT OR UPDATE ON articles
# FOR EACH ROW EXECUTE FUNCTION
# tsvector_update_trigger(search_vector, 'pg_catalog.english', title, content);
Article.search_vector("crystal & programming", "search_vector")
Article.search_vector("crystal | ruby", :search_vector, config: "simple")
Overload: Accepts Symbol for vector column
Searches using a pre-computed tsvector column with plain text query
Article.search_vector_plain("crystal programming", "search_vector")
Article.search_vector_plain("crystal programming", :search_vector)
Overload: Accepts Symbol for vector column
Searches using a pre-computed tsvector column with ranking
Article.search_vector_ranked("crystal", "search_vector")
Article.search_vector_ranked("crystal", :search_vector, rank_normalization: 1)
Article.search_vector_ranked("crystal", :search_vector, rank_function: RankFunction::RankCD)
Overload: Accepts Symbol for vector column
Performs full-text search with weighted columns
Article.search_weighted("crystal", {"title" => Weight::A, "content" => Weight::B})
Article.search_weighted("crystal", {title: Weight::A, content: Weight::B})
Overload: Accepts Symbol keys for weighted columns