unaccent 是一种从词素中移除重音(变音符号)的文本搜索字典。它是一个过滤字典,这意味着它的输出总是被传递给下一个字典(如果有的话),这与字典的常规行为不同。这使得全文搜索可以按不区分重音的方式处理。
unaccent 的当前实现不能用作 thesaurus 字典的规范化字典。
该模块被视为“可信”模块,也就是说,拥有当前数据库 CREATE 权限的非超级用户也可以安装它。
unaccent 字典接受以下选项:
RULES 是包含翻译规则列表的文件的基本名称。该文件必须存储在 $SHAREDIR/tsearch_data/ 中(其中 $SHAREDIR 表示 PostgreSQL 安装的共享数据目录)。其名称必须以 .rules 结尾(该后缀不包含在 RULES 参数中)。
规则文件具有以下格式:
每一行代表一条翻译规则,由一个带重音的字符及其后一个不带重音的字符组成。第一个字符被翻译为第二个字符。例如,
À A Á A Â A Ã A Ä A Å A Æ AE
这两个字符必须以空白分隔,行首或行尾的空白会被忽略。
或者,如果一行中只给出一个字符,该字符的实例会被删除;这对于以独立字符表示重音的语言很有用。
实际上,每个“字符”可以是任何不含空白的字符串,因此 unaccent 字典除了移除变音符号之外,还可用于其他类型的子串替换。
某些字符(例如数字符号)可能在其翻译规则中需要空白。这种情况下可以在被翻译字符周围使用双引号。在翻译字符中包含双引号时,需要用第二个双引号对其进行转义。例如:
¼ " 1/4" ½ " 1/2" ¾ " 3/4" “ """" ” """"
与其他 PostgreSQL 文本搜索配置文件一样,规则文件必须以 UTF-8 编码存储。加载时数据会被自动转换为当前数据库的编码。包含无法翻译字符的行会被静默忽略,因此规则文件可以包含在当前编码下不适用的规则。
在安装 unaccent 模块时,会向 $SHAREDIR/tsearch_data/ 安装 unaccent.rules,其中包含一个对大多数欧洲语言直接有用的更完整示例。该规则文件将带重音的字符翻译为相同的不带重音字符,并且还将连字展开为等效的简单字符序列(例如,Æ 展开为 AE)。
安装 unaccent 扩展会创建一个文本搜索模板 unaccent 以及一个基于它的字典 unaccent。unaccent 字典的默认参数设置为 RULES='unaccent',这使它可以立即配合标准的 unaccent.rules 文件使用。如果需要,你可以修改该参数,例如
mydb=# ALTER TEXT SEARCH DICTIONARY unaccent (RULES='my_rules');
也可以基于该模板创建新的字典。
要测试该字典,可以尝试:
mydb=# select ts_lexize('unaccent','Hôtel');
ts_lexize
-----------
{Hotel}
(1 row)
下面是一个展示如何将 unaccent 字典插入文本搜索配置的示例:
mydb=# CREATE TEXT SEARCH CONFIGURATION fr ( COPY = french );
mydb=# ALTER TEXT SEARCH CONFIGURATION fr
ALTER MAPPING FOR hword, hword_part, word
WITH unaccent, french_stem;
mydb=# select to_tsvector('fr','Hôtels de la Mer');
to_tsvector
-------------------
'hotel':1 'mer':4
(1 row)
mydb=# select to_tsvector('fr','Hôtel de la Mer') @@ to_tsquery('fr','Hotels');
?column?
----------
t
(1 row)
mydb=# select ts_headline('fr','Hôtel de la Mer',to_tsquery('fr','Hotels'));
ts_headline
------------------------
<b>Hôtel</b> de la Mer
(1 row)
unaccent() 函数从给定字符串中移除重音(变音符号)。它基本上是 unaccent 类型字典的包装,但可以在常规文本搜索上下文之外使用。
unaccent([dictionaryregdictionary, ]stringtext) returnstext
如果省略 dictionary 参数,则使用名为 unaccent 且与 unaccent() 函数本身位于同一模式中的文本搜索字典。
例如:
SELECT unaccent('unaccent', 'Hôtel');
SELECT unaccent('Hôtel');