使用"简单"和"英语"时,tsvector上的"to_tsquery"产生不同的结果?

pha*_*kat 13 sql postgresql full-text-search tsvector

我已经被邀请参与一个项目的帮助,并且在几年没有使用它之后我又回到了PostgreSQL.除了缺乏使用之外,我以前从未遇到使用tsvector字段,现在发现自己面临着基于它们的错误.我阅读了关于字段类型及其目的的文档,但是我很难将关于"简单"与"英语"的区别的文档作为to_tsquery()的第一个参数进行挖掘

> SELECT to_tsvector('mortgag') @@ to_tsquery('simple', 'mortgage')
?column? 
----------
 f
(1 row)

> SELECT to_tsvector('mortgag') @@ to_tsquery('english', 'mortgage')
?column? 
----------
 t
(1 row)
Run Code Online (Sandbox Code Playgroud)

我认为他们都应该回归真实,但显然第一次没有 - 为什么?

mu *_*ort 23

FTS利用词典来规范化文本:

12.6.字典

字典用于消除不应在搜索中考虑的单词(停用单词),并对单词进行标准化,以使相同单词的不同派生形式匹配.成功标准化的单词称为lexeme.

因此,词典被用来抛弃在搜索中停留的常见或无意义的东西(停用词)并将其他一切归一化,例如,城市城市即使它们是不同的词也会匹配.

让我们看看一些输出ts_debug,看看字典发生了什么:

=> select * from ts_debug('english', 'mortgage');
   alias   |   description   |  token   |  dictionaries  |  dictionary  |  lexemes  
-----------+-----------------+----------+----------------+--------------+-----------
 asciiword | Word, all ASCII | mortgage | {english_stem} | english_stem | {mortgag}

=> select * from ts_debug('simple', 'mortgage');
   alias   |   description   |  token   | dictionaries | dictionary |  lexemes   
-----------+-----------------+----------+--------------+------------+------------
 asciiword | Word, all ASCII | mortgage | {simple}     | simple     | {mortgage}
Run Code Online (Sandbox Code Playgroud)

请注意,simple使用simple字典而english使用english_stem字典.

simple词典:

通过将输入令牌转换为小写并根据停用词文件进行检查来进行操作.如果在文件中找到它,则返回一个空数组,导致该标记被丢弃.如果不是,则该词的低句形式将作为标准化词汇返回.

这本simple词典只是抛出了停止词,下颚,这就是它.我们可以看到它的简单性:

=> select to_tsquery('simple', 'Mortgage'), to_tsquery('simple', 'Mortgages');
 to_tsquery | to_tsquery  
------------+-------------
 'mortgage' | 'mortgages'
Run Code Online (Sandbox Code Playgroud)

simple词典是太简单了,即使处理简单的复数.

那么这本english_stem词典到底是什么?"词干"后缀是一个赠品:这个词典将词干算法应用于单词以将城市城市转换为相同的东西.从精细手册:

12.6.6.雪球词典

Snowball词典模板基于Martin Porter的一个项目,他是流行的Porter英语词干算法的发明者.[...]每种算法都了解如何将单词的常见变体形式减少到其语言中的基础或词干拼写.

就在下面我们看到english_stem字典:

CREATE TEXT SEARCH DICTIONARY english_stem (
    TEMPLATE = snowball,
    Language = english,
    StopWords = english
);
Run Code Online (Sandbox Code Playgroud)

因此english_stem字典会产生词语,我们可以看到这种情况发生:

=> select to_tsquery('english', 'Mortgage'), to_tsquery('english', 'Mortgages');
 to_tsquery | to_tsquery 
------------+------------
 'mortgag'  | 'mortgag'
Run Code Online (Sandbox Code Playgroud)

执行摘要:'simple'暗示简单的文字匹配,'english'应用词干(希望)产生更好的匹配.词干转按揭mortgag这给了你你的对手.