如何让PostgreSQL的plainto_tsquery用OR(|)而非AND(&)分隔词干?
实现PostgreSQL中类似plainto_tsquery的OR版文本查询
先回顾PostgreSQL 15.1中plainto_tsquery的行为:
它会将未格式化的文本解析、标准化(和to_tsvector逻辑一致),然后在保留的词元之间用&(AND)连接成tsquery。示例如下:
# select plainto_tsquery('english', 'postgres is the best'); plainto_tsquery ------------------- 'postgr' & 'best' (1 row)
这等价于直接用to_tsquery指定AND逻辑:
select to_tsquery('english', 'postgr & best'); to_tsquery ------------------- 'postgr' & 'best'
如果想要实现相同的解析标准化逻辑,但用|(OR)连接词元,比如输入"postgres is the best"得到'postgr' | 'best',可以用以下两种方式:
方法1:直接用SQL语句拼接
通过to_tsvector提取标准化词元,再拼接成OR逻辑的查询字符串,最后转成tsquery:
SELECT to_tsquery('english', string_agg(lexeme, ' | ')) FROM unnest(to_tsvector('english', 'postgres is the best'));
执行结果:
to_tsquery ------------------- 'postgr' | 'best'
方法2:自定义函数封装逻辑
如果需要重复调用,可以封装成自定义函数,用法和plainto_tsquery一致:
CREATE OR REPLACE FUNCTION plainto_tsquery_or(config regconfig, text text) RETURNS tsquery AS $$ SELECT to_tsquery(config, string_agg(lexeme, ' | ')) FROM unnest(to_tsvector(config, text)); $$ LANGUAGE sql IMMUTABLE;
调用示例:
SELECT plainto_tsquery_or('english', 'postgres is the best');
返回结果同样是'postgr' | 'best'。
原理说明
两种方法都复用了PostgreSQL文本搜索的核心逻辑:用to_tsvector处理输入文本,自动过滤停用词(比如示例中的is、the)并提取词干(比如postgres转为postgr),之后将保留的词元用|连接,最终转为tsquery类型。
内容的提问来源于stack exchange,提问作者dfrankow
相关产品推荐
相关产品推荐

