sql 183 lines · 2 tabs

Full-text search with PostgreSQL and tsvector

Maria Garcia Feb 2026
2 tabs
-- Create table with tsvector column
CREATE TABLE articles (
  id SERIAL PRIMARY KEY,
  title VARCHAR(200),
  content TEXT,
  author VARCHAR(100),
  published_at TIMESTAMP,
  search_vector tsvector
);

-- Populate search vector (combines title and content)
UPDATE articles
SET search_vector =
  setweight(to_tsvector('english', COALESCE(title, '')), 'A') ||
  setweight(to_tsvector('english', COALESCE(content, '')), 'B');

-- Create GIN index for fast searching
CREATE INDEX idx_articles_search ON articles USING GIN(search_vector);

-- Basic search query
SELECT title, content
FROM articles
WHERE search_vector @@ to_tsquery('english', 'postgresql & performance');

-- Search with OR
SELECT title
FROM articles
WHERE search_vector @@ to_tsquery('english', 'database | sql');

-- Search with NOT
SELECT title
FROM articles
WHERE search_vector @@ to_tsquery('english', 'postgresql & !mysql');

-- Phrase search (words in order)
SELECT title
FROM articles
WHERE search_vector @@ phraseto_tsquery('english', 'query optimization');

-- Plain text search (auto-converts to tsquery)
SELECT title
FROM articles
WHERE search_vector @@ plainto_tsquery('english', 'database performance tuning');

-- Web search syntax (PostgreSQL 11+)
SELECT title
FROM articles
WHERE search_vector @@ websearch_to_tsquery('english',
  '"database optimization" -mysql OR postgresql');

-- Ranking results by relevance
SELECT
  title,
  ts_rank(search_vector, query) AS rank
FROM articles,
     to_tsquery('english', 'postgresql & performance') query
WHERE search_vector @@ query
ORDER BY rank DESC;

-- Advanced ranking (weights title higher)
SELECT
  title,
  ts_rank_cd(search_vector, query, 32) AS rank
FROM articles,
     to_tsquery('english', 'database') query
WHERE search_vector @@ query
ORDER BY rank DESC;

-- Highlight matches
SELECT
  title,
  ts_headline('english', content, query,
    'StartSel=<mark>, StopSel=</mark>, MaxWords=50') AS snippet
FROM articles,
     to_tsquery('english', 'postgresql') query
WHERE search_vector @@ query;
2 files · sql Explain with highlit

Full-text search finds documents matching text queries. PostgreSQL tsvector stores processed documents optimized for search. I use tsquery for search queries with operators—AND, OR, NOT. GIN indexes on tsvector columns enable fast search. Text search configurations handle language-specific stemming. Ranking functions score results by relevance. Phrase search finds exact multi-word matches. Highlighting shows matched terms in context. Full-text search outperforms LIKE for text-heavy applications. Understanding lexemes, dictionaries, and configurations improves search quality. Triggers maintain tsvector columns automatically. Full-text search is essential for content management, documentation, e-commerce. PostgreSQL's built-in search rivals dedicated search engines for many use cases.


Related snips

sql
-- Simple function
CREATE OR REPLACE FUNCTION get_full_name(
  first_name VARCHAR,
  last_name VARCHAR
)
RETURNS VARCHAR AS $$

Stored procedures and functions in PostgreSQL

postgresql stored-procedures functions
by Maria Garcia 2 tabs
erb
<form data-controller="query-sync" data-action="change->query-sync#apply">
  <select name="status" class="rounded border p-2">
    <option value="">Any</option>
    <option value="open">Open</option>
    <option value="closed">Closed</option>
  </select>

Filter UI that syncs query params via Stimulus (no front-end router)

rails hotwire stimulus
by Henry Kim 2 tabs
ruby
class AddSettingsToAccounts < ActiveRecord::Migration[7.1]
  disable_ddl_transaction!

  def change
    add_column :accounts, :settings, :jsonb, null: false, default: {}

Postgres JSONB Partial Index for Feature Flags

rails postgres jsonb
by codesnips 3 tabs
sql
-- EXPLAIN ANALYZE (actual execution statistics)
EXPLAIN ANALYZE
SELECT u.username, COUNT(o.id) AS order_count
FROM users u
LEFT JOIN orders o ON u.id = o.user_id
WHERE u.created_at >= '2024-01-01'

Advanced query optimization techniques

database optimization query-performance
by Maria Garcia 2 tabs
sql
-- Publisher: Send notification
NOTIFY new_order, 'Order #12345 created';

-- Subscriber: Listen for notifications
LISTEN new_order;

PostgreSQL LISTEN/NOTIFY for pub-sub messaging

postgresql listen-notify pub-sub
by Maria Garcia 2 tabs
sql
-- Logical backup with pg_dump
-- Single database
-- pg_dump -h localhost -U postgres -d mydb -F c -f mydb_backup.dump

-- All databases
-- pg_dumpall -h localhost -U postgres -f all_databases.sql

Database backup and recovery strategies

database backup recovery
by Maria Garcia 2 tabs

Share this code

Here's the card — post it anywhere.

Full-text search with PostgreSQL and tsvector — share card
Link copied