PostgreSQL 中文全文检索原理与实战:结合 jieba 分词实现高效搜索
PostgreSQL 原生中文全文检索支持较弱。文章解析了 tsvector、tsquery 及排名函数原理,提出应用端使用 jieba 分词配合数据库 GIN 索引的方案。通过 Python 脚本演示数据插入与权重设置,展示布尔查询与相关性排序实战,实现高性能中文搜索。

PostgreSQL 原生中文全文检索支持较弱。文章解析了 tsvector、tsquery 及排名函数原理,提出应用端使用 jieba 分词配合数据库 GIN 索引的方案。通过 Python 脚本演示数据插入与权重设置,展示布尔查询与相关性排序实战,实现高性能中文搜索。

在信息爆炸的时代,快速、精准地从海量数据中检索信息至关重要。PostgreSQL 作为功能强大的开源数据库,内置了高效的全文检索引擎。然而,其原生能力对中文支持不佳。本文将深入剖析 PostgreSQL 全文检索的核心原理,讲解 to_tsvector、to_tsquery、ts_rank_cd 等关键函数的用法,并通过一个完整的实战案例,展示如何结合业界流行的 jieba 分词库,在应用程序端完成中文分词,再利用 PostgreSQL 的强大功能实现高性能的中文全文检索。
你是否还在使用 SELECT * FROM articles WHERE content LIKE '%人工智能%'; 来进行搜索?这种方式虽然简单,但存在明显缺陷:
PostgreSQL 的全文检索功能正是为解决这些问题而生。它通过一套标准化的流程,将文本转换为一种易于快速查询的特殊格式。
PostgreSQL 全文检索的工作流程可以简化为以下几个步骤:
理解了原理后,我们来看看实现这一切的核心函数。
这个函数是全文检索的入口,它负责将文本转换为 tsvector。
示例:
-- 使用 'english' 配置
SELECT to_tsvector('english','PostgreSQL is a powerful and open-source relational database.');
结果:
'databas':8 'open-sourc':6 'power':3 'postgresql':1 'relat':7
可以看到,'powerful'被词干提取为'power','database'变为'databas',并且'is', 'a', 'and'等停用词被过滤掉了。
这个函数将用户的搜索字符串转换为一个 tsquery 对象,用于在 tsvector 中进行匹配。
querytext:用户输入的搜索词。它支持布尔操作符:
示例:
-- 搜索同时包含 'powerful' 和 'database' 的文档
SELECT to_tsquery('english','powerful & database');
结果:
'power' & 'databas'
to_tsquery 同样会对查询词进行词干提取。
这是全文检索的匹配操作符,用于判断一个 tsvector 是否匹配一个 tsquery。
示例:
SELECT to_tsvector('english','PostgreSQL is powerful.') @@ to_tsquery('english','powerful');
结果:
t
返回 t (true) 表示匹配成功。
这个函数用于计算匹配的相关性得分。cd 代表'cover density',这是一种考虑了词位在文档中紧密程度的排名算法,通常比基础的 ts_rank 效果更好。
示例:
SELECT ts_rank_cd( to_tsvector('english','PostgreSQL is a powerful database.'), to_tsquery('english','powerful & database'));
结果:
0.0607927
返回一个浮点数得分。得分越高,代表文档与查询的相关性越强。
理论讲完,现在我们进入实战环节。我们将创建一个文章表,用 Python 和 jieba 分词,然后存入 PostgreSQL,最后进行搜索。
安装 Python 依赖库:
pip install psycopg2-binary jieba
我们创建一个 articles 表,包含原始内容和用于检索的 tsvector 字段,并为其创建 GIN 索引。
-- 连接到你的数据库后执行
CREATE TABLE articles (
id SERIAL PRIMARY KEY,
title VARCHAR(255) NOT NULL,
content TEXT NOT NULL,
search_vector tsvector -- 用于存储分词后的词向量
);
-- 创建 GIN 索引,这是高性能检索的关键
CREATE INDEX idx_articles_search_vector ON articles USING GIN(search_vector);
下面的 Python 脚本负责连接数据库,使用 jieba 对中文文本进行分词,并将数据插入表中。
import psycopg2
import jieba
# 数据库连接配置
DB_CONFIG = {
'dbname': 'your_db',
'user': 'your_user',
'password': 'your_password',
'host': 'localhost'
}
def chinese_segment(text):
"""使用 jieba 分词,返回空格分隔的字符串"""
seg_list = jieba.cut(text, cut_all=False)
return " ".join(seg_list)
if __name__ == '__main__':
articles_to_insert = [
{'title': '人工智能:改变世界的驱动力', 'content': '人工智能(AI)是一门让计算机能够执行通常需要人类智能才能完成的任务的科学与工程学科。从语音助手到自动驾驶,AI 正在深刻地改变着我们的生活和工作方式。'},
{'title': '机器学习入门:从理论到实践', 'content': '机器学习是人工智能的核心。它涉及算法的设计,这些算法能够让计算机从数据中学习模式并做出预测。'},
{'title': 'Python 编程的艺术', 'content': 'Python 是一种解释型、面向对象、动态数据类型的高级程序设计语言。它以其简洁的语法和强大的生态系统而闻名。'}
]
conn = None
try:
conn = psycopg2.connect(**DB_CONFIG)
with conn.cursor() as cur:
for art in articles_to_insert:
# 分词并为标题和内容设置不同权重 (A > B)
seg_title = chinese_segment(art['title'])
seg_content = chinese_segment(art['content'])
tsvector_str = f"{seg_title}A {seg_content}B"
cur.execute(, (art[], art[], tsvector_str))
()
Exception e:
()
conn:
conn.rollback()
:
conn:
conn.close()
代码解释:
现在,我们可以在数据库中进行搜索了。
场景 1:搜索包含'人工智能'的文章
SELECT id, title, ts_rank_cd(search_vector, query) AS relevance_score
FROM articles, to_tsquery('simple','人工智能') AS query
WHERE search_vector @@ query
ORDER BY relevance_score DESC;
结果:标题包含'人工智能'的文章会排在前面,且得分更高。
场景 2:搜索包含'机器学习'但不包含'Python'的文章
SELECT id, title, ts_rank_cd(search_vector, query) AS relevance_score
FROM articles, to_tsquery('simple','机器学习 & !Python') AS query
WHERE search_vector @@ query
ORDER BY relevance_score DESC;
结果:只会返回第二篇关于机器学习的文章。
通过本文的学习,我们掌握了 PostgreSQL 全文检索的核心原理和实现方法。

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online
基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online
在线格式化和美化您的 SQL 查询(它支持各种 SQL 方言)。 在线工具,SQL 美化和格式化在线工具,online
解析 INSERT 等受限 SQL,导出为 CSV、JSON、XML、YAML、HTML 表格(见页内语法说明)。 在线工具,SQL转CSV/JSON/XML在线工具,online
CSV 与 JSON/XML/HTML/TSV/SQL 等互转,单页多 Tab。 在线工具,CSV 工具包在线工具,online