PostgreSQL中的全文搜索与模糊搜索的结合

9
我希望在PostgreSQL中实现全文搜索并结合模糊搜索。我在测试区域遵循了这篇文章:https://blog.lateral.io/2015/05/full-text-search-in-milliseconds-with-postgresql/,一切都运行良好。但有时我的搜索字符串中会有空格和没有空格的情况,比如我在‘title’列中有一个条目是'test123',我的搜索字符串看起来像 'test 123' 带一个空格。如何在这种情况下得到匹配结果?我的搜索SQL查询如下:
SELECT * 
FROM test, plainto_tsquery('test:*&123:*') as q 
WHERE (tsv @@ q)

result: 0 rows

我尝试着想找出是否可以将pg_trgm和ts_vector结合使用,但是我找不到解决方法。你有什么想法吗?

1个回答

16

正如解析文档所述:

...plainto_tsquery不会在其输入中识别tsquery运算符、权重标签或前缀匹配标签...

plainto_tsqueryphraseto_tsquery是方便的函数,使全字符串搜索更加容易,但它们不支持所有功能。相反,请使用接受完整搜索语法的to_tsquery

SELECT * 
FROM test, to_tsquery('testing:* & 123:*') as q 
WHERE (tsv @@ q)

这个函数还要求您以与使用to_tsvector规范化搜索文本相同的方式规范化搜索查询,但是通过一些字符串函数很容易实现:

SELECT string_agg(lexeme || ':*', ' & ' order by positions) 
FROM unnest(to_tsvector('testing 123'))

这基本上是从to_tsvector获取单个标记,将:*附加到每个标记,然后使用&连接它们以创建单个字符串。上面的示例将testing 123转换为testing:* & 123:*,您可以直接使用to_tsquery进行模糊匹配并保持规范化。

您可以将所有内容组合成CTE以使其简单:

WITH search AS (
    SELECT to_tsquery(string_agg(lexeme || ':*', ' & ' order by positions)) AS query
    FROM unnest(to_tsvector('enter your search query here'))
)
SELECT test.*
FROM test, search
WHERE (test.tsv @@ search.query)

这假设表中有一个预生成的tsv数据类型的tsquery列,而不是在每个查询中创建它(这样会慢得多)。PG12+支持生成列,可以自动更新它。
更详细的答案请参阅我的博客:https://manigandham.com/post/fuzzy-fulltext-search-postgresql

我似乎漏掉了什么。这不是模糊匹配,只是前缀匹配,对吗?我试图复制一个类似于原始帖子中的示例,但即使对我来说也无法正常工作,因为它只匹配前缀而不是后缀。但即使示例对于前缀和后缀都有效,它仍然不是模糊匹配,对吗?模糊匹配意味着samethingsomething是匹配的。我使用的是PostgreSQL 11.20版本。 - Manuel Schmidt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接