-- 连接到你的数据库后执行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);
第 3 步:应用端数据插入与分词
下面的 Python 脚本负责连接数据库,使用 jieba 对中文文本进行分词,并将数据插入表中。
import psycopg2
import jieba
# 数据库连接配置
DB_CONFIG = {
'dbname': 'your_db',
'user': 'your_user',
'password': 'your_password',
'host': 'localhost'
}
defchinese_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 = Nonetry:
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("""
INSERT INTO articles (title, content, search_vector) VALUES (%s, %s, to_tsvector('simple', %s));
""", (art['title'], art['content'], tsvector_str))
print("数据插入成功!")
except Exception as e:
print(f"发生错误:{e}")
if conn:
conn.rollback()
finally:
if conn:
conn.close()
代码解释:
chinese_segment 函数使用 jieba 对中文进行分词。
f"{seg_title}A {seg_content}B" 是一个技巧:我们给标题的词加上 A 权重,内容的词加上 B 权重。这样,标题中出现的关键词在排序时会得到更高的分数。
SELECT id, title, ts_rank_cd(search_vector, query) AS relevance_score
FROM articles, to_tsquery('simple','人工智能') AS query
WHERE search_vector @@ query
ORDERBY 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
ORDERBY relevance_score DESC;
结果:只会返回第二篇关于机器学习的文章。
总结
通过本文的学习,我们掌握了 PostgreSQL 全文检索的核心原理和实现方法。
核心价值:PostgreSQL 全文检索通过 tsvector 和 tsquery 的转换,实现了远超 LIKE 的查询性能和功能。