LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

解放你的搜索功能!深入浅出PostgreSQL全文搜索(FTS)实战指南

maoxiaoming
2025年8月23日 17:21 本文热度 65

引言:为什么不用LIKE?

当我们需要在文章、帖子或产品描述中搜索关键词时,第一个蹦进脑海的可能是SQL的LIKEILIKE操作符:

sql
SELECT * FROM posts WHERE body LIKE '%postgres%';

这种方式简单但问题很多:

  1. 性能极差%postgres%这种前导通配符无法利用索引,会导致全表扫描

  2. 不够智能:它只能进行严格的字符匹配。搜索"run",不会找到"running""ran"

  3. 没有相关性排序:它只能告诉你“有”或“没有”,无法告诉你哪条结果更相关。

而PostgreSQL内置的全文搜索(Full-Text Search, FTS) 就是为了解决这些问题而生的。


一、核心概念:文档、向量与查询

PostgreSQL的FTS将搜索过程抽象为三步:

  1. 文档(Document):待搜索的文本单元。可以是一篇文章、一条评论,或者由多个字段组合而成的文本(如 title || ' ' || body)。

  2. 向量(tsvector):对文档进行处理后的产物。它:

    • 解析和分词:将文本拆分成一个个独立的 token(词位)。

    • 标准化:转换为小写。

    • 去除停用词:移除atheis等常见但无搜索意义的词。

    • 提取词干:将单词变为其词根形式(如 running -> run)。

    • 最终存储的是(词位, 位置)形式的列表。

  3. 查询(tsquery):代表用户要搜索的内容。它也可以进行词干提取,并支持逻辑操作符(& 与, | 或, ! 非)。

搜索的本质,就是判断 @@ 操作符两边的 tsvector 和 tsquery 是否匹配。


二、逐行详解示例SQL

拆解以下SQL语句:

sql
SELECT title, body
FROM posts
WHERE to_tsvector('english', body) @@ to_tsquery('english', 'postgres & optimization');
  • to_tsvector('english', body)

    • 功能:生成一个 tsvector

    • 参数1:'english':这是一个文本搜索配置(Text Search Configuration)。它决定了使用哪种语言的规则进行分词、停用词处理和词干提取。PostgreSQL支持多种语言(如simpleenglishspanishrussian等)。配置的选择直接影响搜索结果。

    • 参数2:body:需要被处理的文本字段。

    • 结果示例:假设body字段内容是 "PostgreSQL provides powerful optimization tools.",经过处理后会变成: 'power':5 'optim':6 'postgresql':1 'provid':2 'tool':7。可以看到,provides变成了provid(词干提取),the被移除(停用词)。

  • to_tsquery('english', 'postgres & optimization')

    • 功能:生成一个 tsquery

    • 参数1:'english':同样需要指定配置,确保查询词和处理文档时使用相同的规则(例如,optimization也会被提取词干为optim)。

    • 参数2:'postgres & optimization':查询字符串。&表示同时包含这两个词。

    • 结果:一个代表包含词干 'postgres' 且 包含词干 'optim'的查询对象。

  • @@ 操作符

    • 功能:布尔匹配操作符。如果左边生成的 tsvector 匹配右边生成的 tsquery,则返回true,该行记录就会被选中。


三、超越基础:排名与高亮

仅仅找到匹配的文档还不够,我们通常需要最好的结果排在前面。

  1. 相关性排名(Ranking): 使用ts_rank函数。

    sql
    SELECT title, body,
           ts_rank(to_tsvector('english', body), 
                   to_tsquery('english', 'postgres & optimization')) AS rank
    FROM posts
    WHERE to_tsvector('english', body) @@ to_tsquery('english', 'postgres & optimization')
    ORDER BY rank DESC;

    ts_rank会根据词位出现的频率、位置等因素计算一个相关性分数,然后通过ORDER BY rank DESC将最相关的结果排在顶部。

  2. 结果高亮(Highlighting): 使用ts_headline函数。

    sql
    SELECT title,
           ts_headline('english', body, 
                       to_tsquery('english', 'postgres & optimization')) AS headline
    FROM posts
    WHERE ...;

    ts_headline会在结果中环绕匹配到的词加上诸如<b>...</b>这样的HTML标签,让用户在上下文中一眼就看到为什么这条结果被匹配上了,体验堪比专业搜索引擎。


四、性能优化:GiST/GIN 索引

WHERE子句中使用函数调用(如to_tsvector(...))通常会导致无法使用索引。为了让全文搜索飞起来,必须创建专门的索引

首选GIN索引,它专为这种“多值列”(一个tsvector里包含很多个词位)的查询而优化。

sql
-- 1. 创建一个生成的tsvector列(推荐,易于管理和索引)
ALTER TABLE posts
ADD COLUMN body_tsvector tsvector
GENERATED ALWAYS AS (to_tsvector('english', COALESCE(body, ''))) STORED;
-- 2. 在生成的列上创建GIN索引
CREATE INDEX idx_posts_body_fts ON posts USING GIN(body_tsvector);
-- 3. 查询语句变得更简单高效
SELECT title, body
FROM posts
WHERE body_tsvector @@ to_tsquery('english', 'postgres & optimization');

五、与Elasticsearch的比较

特性PostgreSQL FTSElasticsearch
部署复杂度零成本,内置,无需额外部署需要单独部署和维护另一个分布式系统
数据一致性强一致,搜索和事务在同一数据库,无延迟最终一致,数据同步有延迟(取决于刷新间隔)
功能丰富度支持基础到中级的需求(分词、排名、高亮)极其丰富,专业的分布式搜索引擎,支持聚合分析、同义词、拼音搜索等
性能与扩展性单机性能优秀,可通过分片扩展大规模分布式搜索和水平扩展而生

结论:如何选择?

  • 使用PostgreSQL FTS:如果你的搜索需求是应用内的、非核心的(如博客搜索、后台管理搜索),并且你希望保持技术栈简单、保证数据一致性。

  • 使用Elasticsearch:如果你的业务核心是搜索(如电商平台、新闻网站),需要处理海量数据、复杂的搜索逻辑和高吞吐量。

总结

PostgreSQL的全文搜索是一个被严重低估的“隐藏宝石”。它提供了一个在** simplicity(简单性)** 和 power(功能) 之间绝佳平衡的解决方案。对于许多不需要Elasticsearch这种“重武器”的应用场景来说,它完全足够且是更优雅的选择。

通过本文的介绍,希望你能在你的下一个项目中轻松上手这项强大功能!

讨论点:

  1. 大家在项目中是用PG的全文搜索还是ES?为什么做出这个选择?

  2. 在处理中文全文搜索时,有什么好的配置或分词方案推荐吗?(这是一个常见痛点,可以引出zhparser等扩展的讨论)



该文章在 2025/8/23 17:22:12 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2025 ClickSun All Rights Reserved