本文将详细介绍如何在PolarDB PostgreSQL版(兼容Oracle)中,利用zhparser扩展来解决 PostgreSQL 内置全文检索功能无法有效处理中文的难题。通过集成此扩展,您可以轻松实现高效、精准的中文全文检索。
启用中文分词
启用扩展。
CREATE EXTENSION IF NOT EXISTS zhparser;创建中文分词配置。
-- 创建一个名为 zh_cfg 的配置,并指定解析器为 zhparser CREATE TEXT SEARCH CONFIGURATION zh_cfg (PARSER = zhparser); -- 为特定类型的词元(如名词n, 动词v, 形容词a等)添加映射 -- 这里使用 'simple' 字典,它会进行小写转换并检查停用词 ALTER TEXT SEARCH CONFIGURATION zh_cfg ADD MAPPING FOR n,v,a,i,e,l WITH simple;设定全局参数。
zhparser提供了一些可调整的参数,您可以通过ALTER ROLE或ALTER DATABASE进行设置。-- 示例:开启“多元短语”模式,会尝试组合相邻的单字以形成更长的词 ALTER ROLE ALL SET zhparser.multi_short = ON;测试分词效果。
-- 1. 测试基本的词法分析 (ts_parse) SELECT * FROM ts_parse('zhparser', '2011年,保障房进入了更大规模的建设阶段。'); -- 2. 测试将文本转换为词向量 (to_tsvector) -- 这里使用我们刚刚创建的配置 'zh_cfg' SELECT to_tsvector('zh_cfg', '与2011年相比,2012年的保障房建设在资金配套上的压力将更为严峻。'); -- 3. 测试将查询字符串转换为查询树 (to_tsquery) -- '保障房' 和 '资金' 和 '压力' SELECT to_tsquery('zh_cfg', '保障房 & 资金 & 压力');
创建并使用全文索引
准备示例表和数据:
-- 创建一个示例表 t1 CREATE TABLE t1 ( id SERIAL PRIMARY KEY, name TEXT ); -- 插入一些测试数据 INSERT INTO t1 (name) VALUES ('中央加大保障房的建设和投入力度'), ('保障房资金配套压力严峻'), ('防火防盗是安全工作的重点');为目标字段创建 GIN 索引:
我们将为
t1表的name字段创建一个基于zh_cfg配置的 GIN 索引。-- 使用我们创建的 'zh_cfg' 配置为 name 字段创建 GIN 索引 CREATE INDEX idx_gin_t1_name ON t1 USING gin (to_tsvector('zh_cfg', name));执行高效的全文检索查询:
使用
@@操作符进行查询。关键在于WHERE子句中的to_tsvector表达式必须与CREATE INDEX中的表达式完全一致,这样才能确保优化器能够使用我们创建的索引。-- 示例1:查询包含“保障房”的记录 -- 查询表达式 to_tsvector('zh_cfg', name) 与索引定义完全匹配,会高效利用索引 SELECT name FROM t1 WHERE to_tsvector('zh_cfg', name) @@ to_tsquery('zh_cfg', '保障房'); -- 示例2:查询同时包含“保障房”和“资金”的记录 (使用 & 操作符) SELECT name FROM t1 WHERE to_tsvector('zh_cfg', name) @@ to_tsquery('zh_cfg', '保障房 & 资金'); -- 示例3:查询包含“防火”的记录 SELECT name FROM t1 WHERE to_tsvector('zh_cfg', name) @@ to_tsquery('zh_cfg', '防火');