在PostgreSQL中生成tsquery前是否需要手动移除字符串中的冒号等标点?
关于Postgres中websearch_to_tsquery带冒号无法匹配tsvector的问题解答
问题判定:该现象属于已知bug,非预期行为
你观察到的差异是Postgres 12、13版本的已知缺陷,不符合官方文档描述的「其他标点会被忽略」的设计规则,该问题在Postgres 14及以上版本已经完成修复。
根因说明
websearch_to_tsquery在12、13版本中未正确过滤双引号短语内的冒号,会将冒号识别为一个独立的空白占位词,导致生成的tsquery中两个相邻词条被标记为间隔1个词(对应语法c <2> behavior),但to_tsvector会正常丢弃冒号,两个词条实际为相邻关系(对应语法c <-> behavior),二者匹配规则不一致导致查询失败。
临时解决方案
针对还在使用Postgres 12、13版本的场景,确实需要在调用websearch_to_tsquery之前对查询字符串做预处理,移除无关标点。
需要提前移除的字符范围
所有不属于websearch_to_tsquery官方语法的标点都需要提前清理,包括但不限于:
- 冒号
: - 分号
; - 感叹号
! - 问号
? - 逗号
, - 句号
.
预处理示例
可以直接在Postgres中用正则表达式完成清理,示例代码如下:
-- 先清理所有非语法相关的标点,再生成tsquery SELECT websearch_to_tsquery('english', regexp_replace('"Design Patterns in C++: Behavioral - Observer to Visitor"', '[^\w\s "-]', '', 'g') );
执行后生成的tsquery会和移除冒号后的结果一致,可正常匹配对应tsvector。
内容的提问来源于stack exchange,提问作者Brian Bauer
相关产品推荐
相关产品推荐

