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

时间:2012-05-25 01:29:02

标签: 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)

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

1 个答案:

答案 0 :(得分:20)

FTS利用dictionaries来规范化文字:

  

<强> 12.6。字典

     

字典用于消除搜索中不应考虑的单词(停用词),以及规范化单词,以便同一单词的不同派生形式将比赛。成功标准化的单词称为 lexeme

因此,字典用于丢弃在搜索中过于常见或无意义的内容(停用词)并将其他所有内容标准化,以便 city 城市即使它们是不同的词,也会匹配。

让我们看看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}

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

simple dictionary

  

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

simple词典只会抛出停用词,下行词,而这就是它。我们自己可以看到它的简洁性:

=> select to_tsquery('simple', 'Mortgage'), to_tsquery('simple', 'Mortgages');
 to_tsquery | to_tsquery  
------------+-------------
 'mortgage' | 'mortgages'

simple字典太简单了,甚至无法处理简单的复数。

那么这个english_stem字典到底是什么? “词干”后缀是一个赠品:这个词典将词干算法应用于单词以将(例如) city cities 转换为同一个词。来自fine manual

  

<强> 12.6.6。雪球词典

     

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

在下面我们看到english_stem字典:

CREATE TEXT SEARCH DICTIONARY english_stem (
    TEMPLATE = snowball,
    Language = english,
    StopWords = english
);

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

=> select to_tsquery('english', 'Mortgage'), to_tsquery('english', 'Mortgages');
 to_tsquery | to_tsquery 
------------+------------
 'mortgag'  | 'mortgag'

执行摘要'simple'意味着简单的文字匹配,'english'适用于(希望)产生更好的匹配。阻止将抵押转变为 mortgag 并为您提供匹配。