PostgreSQL全文搜索配置unaccent扩展后,无重音词未匹配带重音词的问题排查
嘿,我来帮你捋捋问题出在哪!你已经把unaccent扩展和自定义全文搜索配置都搭好了,但没得到预期的匹配结果,核心问题其实出在你的查询没用到你创建的那个带unaccent的自定义配置,或者当前会话还没生效新的默认配置。
咱们一步步拆解:
首先,你虽然执行了alter database cpn set default_text_search_config to 'portugues_sem_acento';,但这个设置是针对新会话生效的——如果你运行这条命令后没重新连接数据库,当前的会话还是用的旧默认配置(大概率是原生的portuguese)。你可以先查下当前会话的默认配置:
show default_text_search_config;
如果结果不是portugues_sem_acento,要么重新连一下数据库,要么在当前会话里手动执行:
set default_text_search_config to 'portugues_sem_acento';
另外,更稳妥的方式是在查询里显式指定要用的全文搜索配置,彻底避免依赖会话默认配置的坑。把你的查询改成这样:
select to_tsvector('portugues_sem_acento', 'Cação') , to_tsquery('portugues_sem_acento', 'cacao') , to_tsvector('portugues_sem_acento', 'Cação') @@ to_tsquery('portugues_sem_acento', 'cacao') ;
这样执行后,to_tsvector会先用unaccent把Cação转成无重音的cacao,再做词干处理;to_tsquery也会用同样的配置处理cacao,最终匹配结果就会是t(true)。
你之前的查询没指定配置,所以用了旧的默认配置,根本没触发unaccent的处理——这就是为什么你看到to_tsvector返回的是'cação':1,而不是去掉重音后的形式。
对了,你的自定义配置映射顺序是对的:把unaccent放在portuguese_stem前面,必须先去掉重音再做词干提取,不然词干处理会把带重音的词当成完全不同的词来处理。
修改后的查询输出应该是这样的:
to_tsvector | to_tsquery | ?column? -------------+------------+---------- 'cacao':1 | 'cacao' | t (1 row)
备注:内容来源于stack exchange,提问作者Clodoaldo Pinto

