使用 pg_textsearch 进行全文搜索

Cloud SQL for PostgreSQL 中的 pg_textsearch 扩展程序使用业界标准的 BM25(最佳匹配 25)评分算法提供全文搜索,从而提供高度准确的相关性评分。该扩展程序是一个可在 GitHub 上获取的开源项目。

pg_textsearch 扩展程序需要 PostgreSQL 17 或更高版本。

由于 pg_textsearch 支持逆文档频率、词频饱和度和文档长度归一化,因此它可以生成比 PostgreSQL 的内置 ts_rank 函数更相关的结果。此外,由于它直接在标准 PostgreSQL 存储页面上运行,因此您无需安装 Elasticsearch 等外部引擎,也无需担心双集群维护和数据同步问题。借助 pg_textsearch,您无需离开 PostgreSQL 生态系统,即可构建强大、可伸缩且高度相关的搜索体验。

在 Cloud SQL for PostgreSQL 中,有多种文本搜索选项:

  • 完全匹配:使用标准 SQL 搜索时,您可以使用 LIKE 和 ILIKE 语句来扫描完全匹配的字符序列。例如,查询 ILIKE '%smart fitness watches%' 会找到如下实例:

    • “探索我们正在促销的新款智能健身手表。”
    • “智能健身手表是绝佳的礼物。”

    但是,它无法找到:

    • “跑步者想要一款智能防水健身手表。”
    • “这款手表在健身方面特别智能。”
  • 全文搜索:全文搜索使用 BM25 算法和 tsvector,将文本拆分为词根,忽略过滤词,并对相关性进行评分。它能理解语言规则(包括复数和语法),并会考虑词频。对 smart AND fitness AND watches 进行全文搜索会找到示例完全匹配查询会漏掉的实例,以及如下所示的更复杂的实例:

    • “智能手表是日常健身的完美搭档。”
    • “并非所有手表在健身方面都如此智能。”

    但是,它无法找到:

    • “一款智能健康感知手表可以帮助您制定锻炼计划。”
    • “这款智能锻炼追踪手环物美价廉。”
  • 语义搜索:语义搜索使用 AI 模型将文本转换为向量并测量相似度距离。它能理解含义、意图、上下文、同义词和相关概念。对 smart fitness watches 进行语义搜索会找到其他搜索方法会错过的示例实例。它会理解“智能健康感知手表”与“智能健身手表”相同,并且“智能运动跟踪手环”也可能相关。如果它没有充分优先考虑“手表”,则可能会错误地匹配计步器手环。

安装 pg_textsearch 扩展程序

请按照以下步骤安装并启用 pg_textsearch:

  1. 按照配置数据库标志中的说明,将 cloudsql.enable_pg_textsearch 标志设置为 on。这会将 pg_textsearch 添加到 shared_preload_libraries。

  2. 安装 pg_textsearch 扩展程序

      CREATE EXTENSION pg_textsearch;
    
  3. 验证安装:

      SELECT extversion FROM pg_extension WHERE extname = 'pg_textsearch'
    

使用pg_textsearch进行搜索

假设以下示例表已填充数据:

CREATE TABLE documents (
    doc_id TEXT PRIMARY KEY,
    content TEXT,
    text_embedding vector(3072)
    GENERATED ALWAYS AS (embedding('gemini-embedding-001', content)) STORED 
  );

在使用全文搜索之前,请先创建 BM25 索引:

CREATE INDEX idx_docs_bm25
      ON documents
      USING bm25 (content)
      WITH (text_config = 'english');

然后,您可以发出如下全文搜索查询:

SELECT doc_id, content, content <@> 'database system'
      AS score FROM documents
      ORDER BY content <@> 'database system'
      ASC LIMIT 5;

使用 pg_textsearch 和 vector 执行混合搜索

您可以将 pg_textsearch 与 vector 语义搜索扩展程序结合使用,以执行混合搜索。安装 vector 语义搜索扩展程序,如下所示:

CREATE EXTENSION IF NOT EXISTS vector CASCADE;

进行混合语义和全文搜索查询,如下所示:

WITH
  -- Semantic search results
  vector_search AS (
    SELECT doc_id,
      RANK () OVER (ORDER BY text_embedding <=>
                             google_ml.embedding('gemini-embedding-001',
                                                 'database')::VECTOR ) AS rank
      FROM documents
      ORDER BY text_embedding <=> google_ml.embedding('gemini-embedding-001',
                                                      'database')::VECTOR
    LIMIT 10
  ),
  -- Full text search results
  text_search AS (
    SELECT doc_id,
      RANK () OVER (ORDER BY content <@> 'database' ASC) AS rank
    FROM documents
    ORDER BY content <@> 'database' ASC
    LIMIT 10
  )
  -- RRF combining both semantic and full text search results
  SELECT
    COALESCE(vector_search.doc_id, text_search.doc_id) AS id,
    COALESCE(1.0 / (60 + vector_search.rank), 0.0) +
    COALESCE(1.0 / (60 + text_search.rank), 0.0) AS rrf_score
  FROM vector_search
    FULL OUTER JOIN text_search ON vector_search.doc_id = text_search.doc_id
  ORDER BY rrf_score DESC
  LIMIT 5;

用于配置 pg_textsearch 扩展程序的标志

使用以下标志配置 pg_textsearch 全文搜索: