PostgreSQL 全文搜索和三元组混淆

Posted

技术标签:

【中文标题】PostgreSQL 全文搜索和三元组混淆【英文标题】:PostgreSQL Full Text Search and Trigram Confusion 【发布时间】:2013-03-30 20:13:04 【问题描述】:

我对 PostgreSQL、全文搜索和 Trigram 的整个概念有点困惑。在我的全文搜索查询中,我使用 tsvector,如下所示:

SELECT * FROM articles
WHERE search_vector @@ plainto_tsquery('english', 'cat, bat, rat');

问题是,这种方法不考虑拼写错误。然后我开始阅读Trigram and pg_trgm

查看其他示例,似乎使用了三元组或使用了向量,但从不同时使用两者。所以我的问题是:它们曾经一起使用过吗?如果是这样,怎么做? trigram 会取代全文吗?三元组更准确吗?三元组对性能的影响如何?

【问题讨论】:

【参考方案1】:

它们的用途截然不同。

全文搜索用于返回匹配词干搜索查询的文档。 三元组为您提供了一种比较两个字符串并确定它们看起来有多相似的方法。

考虑以下示例:

SELECT 'cat' % 'cats'; --true

以上返回 true,因为 'cat''cats' 非常相似(由 pg_trgm 限制决定)。

SELECT 'there is a cat with a dog' % 'cats'; --false

上面返回false,因为%在两个整个字符串之间寻找相似的,而不是在字符串中寻找单词catswithin

SELECT to_tsvector('there is a cat with a dog') @@ to_tsquery('cats'); --true

这将返回true,因为 tsvector 将字符串转换为词干列表并忽略了一堆常用词(停用词 - 像 'is' 和 'a')...然后搜索 @ 的词干版本987654331@.

听起来您想使用三元组来自动更正您的ts_query,但这实际上是不可能的(无论如何也不是以任何有效的方式)。他们并不真正知道一个单词拼写错误,也不知道它与另一个单词有多相似。它们可以用于搜索单词表以尝试查找相似的单词,从而允许您实现“您的意思是...”类型的功能,但是这个单词需要维护一个包含所有单词的单独表search 字段中使用的字词。

如果您希望文本索引匹配一些常见的拼写错误的单词/短语,您可能需要查看Synonym Dictorionaries

【讨论】:

我添加了几个示例来突出每个扩展的%@@ 之间的区别。如果您的目标是查找包含英语(或您有字典的任何已知语言)的文档,那么您就是在寻找全文。如果您的目标是将整个字段与整个字段的字符串进行匹配,并避免拼写错误,那么 pg_trgm 就是您想要的。 感谢您的解释!这清除了很多。好的,看来这个问题可以通过扩展我的字典知识来解决。 我喜欢这个答案。我讨厌这个答案是准确的事实:( 从 Postgres 9.6 开始,trigram 模块 (pg_trgm) 现在具有“单词相似性”功能 - 即它可以在字符串中查找最相似的单词,而不是将查询与整个字符串进行比较。

以上是关于PostgreSQL 全文搜索和三元组混淆的主要内容,如果未能解决你的问题,请参考以下文章

PostgreSQL 中的高效全文搜索,在另一列上排序

PostgreSQL 全文搜索权重/搜索词的优先级

在 PostgreSQL 上使用 SQLAlchemy 创建全文搜索索引

我可以以编程方式配置 PostgreSQL 以不消除全文搜索中的停用词吗?

Django:如何在 Postgresql 中对日语(多字节字符串)进行全文搜索

Postgresql:可以在 lob 内进行全文搜索吗?