Postgres 全文搜索,带有重音和屈折(共轭等)

Tom*_*mek 5 postgresql full-text-search unaccent

我希望能够在 Postgres 中以屈折(波兰)语言搜索无重音的短语。

比如说,如果一个文档包含robi?em,则词位应该是robi?(infinivite)。它的形式有robi?robi?robi?a等等。例如,我希望能够找到它,robie其中包含一个不带重音的短语robi?

我所做的是从一个运行良好的波兰语文本搜索配置开始

CREATE TEXT SEARCH DICTIONARY polish_ispell (
TEMPLATE = pg_catalog.ispell,
dictfile = 'polish', afffile = 'polish', stopwords = 'polish' );
Run Code Online (Sandbox Code Playgroud)

然后我尝试扩展它以包含unaccent.

create extension unaccent;
create text search configuration polish_unaccented (copy = polish);
ALTER TEXT SEARCH CONFIGURATION polish_unaccented   ALTER MAPPING FOR hword, 
hword_part, word WITH unaccen, polish_ispell, simple, ;
Run Code Online (Sandbox Code Playgroud)

遗憾的是,使用此配置无法正确创建词法:

select to_tsvector('polish_unaccented' ,'robi?');

'robil':1
Run Code Online (Sandbox Code Playgroud)

词素当然应该是:

'robi?':1
Run Code Online (Sandbox Code Playgroud)

所以下面不能返回true(这就是我认为我需要的):

select to_tsvector('polish_unaccented','robi?') @@ to_tsquery('polish_unaccented','robie');
Run Code Online (Sandbox Code Playgroud)

我用谷歌搜索但没有找到任何文件显示如何为我的案例真正配置 Postgres。文档仅显示蹩脚的“Hôtels”示例,这不是“词法”一词。

干杯

joa*_*olo 2

AFAIK,你不能用当前的 PostgreSQL 全文配置(字典和解析器/词法分析器)做你想做的事,尽管一些解决方法可能会做一些接近这个技巧的事情。

\n\n

我不懂波兰语,但我在西班牙语方面也遇到过类似的问题(西班牙语也有词形变化等),而且人们已经完全习惯了谷歌能够忽略口音的事实,并且他们也经常忽视它们。

\n\n

词典

\n\n

您可以有多个 PostgreSQL 字典,它们可以做不同的事情,但基本上以某种方式简化您的文本。如果您想将单词转换为其词位,您需要做的是使用ISpell 字典

\n\n
\n

[...] 它可以将一个单词的许多不同语言形式标准化为同一个词位。例如,英语 Ispell 词典可以匹配搜索词“bank”的所有词尾变化和词形变化,例如“banking”、“banked”、“banks”、“banks\'”和“bank\'s”。

\n
\n\n

然而,这本词典(至少在西班牙语中)只能识别正确重音的单词,否则它将无法找出某个(可能有重音的)单词对应的词位。这是因为ISpell 词典(例如波兰语 ISpell 词典)中的条目是使用所有正确的重音符号(或变音符号)[应有的] 编写的。

\n\n

ISpell Polsih 字典由两个文件组成,一个名为pl_PL.dic(编码为 ISO-8859-2,据我猜测,另一个名为pl_PL.aff. 第一个包含词位+适用于它们的规则,第二个包含这些规则的含义。ISpell 软件解释这些文件以找出如何将单词转换为其词位[以及如何检查拼写是否正确]。

\n\n

文件中的条目.dic如下所示:

\n\n
abecad\xc5\x82o/UV\nabecad\xc5\x82owy/bxXyY\n[...]\nAbisy\xc5\x84czyk/NOqsT\nabisy\xc5\x84ski/XxYbyc\n
Run Code Online (Sandbox Code Playgroud)\n\n

.aff文件给出了“U”和“V”以及该符号后面的所有其他字母的含义规则/。有些如果这个规则(我远远不知道)将告诉软件后缀前缀如何适用于单词abecad\xc5\x82o。例如:

\n\n
SFX U   \xc5\x82o        le        [^astz]\xc5\x82o\n
Run Code Online (Sandbox Code Playgroud)\n\n

由于本词典中没有类似abecadlo或 的单词abisynski,因此如果您在搜索中输入这些文本,词典将不会返回任何词位。

\n\n

可能的解决方法:操作字典文件,并将所有带有重音字符的行复制为不重音的等效字符。您可能需要对.aff字典的部分执行类似的操作。

\n\n

也许,您还需要使用同义词词典来使所有单词的重音版本和非重音版本具有相同的含义。

\n\n

这是一种蛮力方法,实际上,您将发明一种“波兰语的新版本,其中带重音的字母与不带重音的字母等效”。[不要告诉字典的制造者是谁制造了字典,以确保人们拼写正确;-)]。

\n\n

我认为这种做法确实有非常多的风险。我知道我不会用西班牙语或加泰罗尼亚语这样做,因为变音符号的存在或不存在可以从根本上改变单词的含义(“a\xc3\xb1o”与“没有太大关系” ano”,西班牙语;考虑它们的同义词是非常微妙的)。

\n\n

您必须评估这是否适用于波兰语。

\n\n
\n\n

替代方案:您可以仅使用简单字典和“过滤”unnacent模块的组合。您不会获得词位,并且该组合能够执行的转换并不那么复杂......但是当您搜索abecad\xc5\x82oabecadlo时,您会得到相同的结果。

\n\n

就我而言,我最终选择了这个解决方案。

\n\n
\n\n

第二种选择:如果您需要能够忽略重音、允许小拼写错误并具有许多复杂可能性的文本搜索,请考虑使用数据库之外的解决方案,例如Apache Solr。这显然是一种非常不同的方法,您需要一些过程来使其与数据库同步。

\n