7

我想在 postgresql 中结合一种模糊搜索来实现全文搜索。对于我的测试区域,我跟进了这篇文章:https ://blog.lateral.io/2015/05/full-text-search-in-milliseconds-with-postgresql/ ,一切正常。但有时我在 search 字符串中有带和不带空格的搜索案例,如下所示:

在我的“标题”列中,有一个类似“ test123 ”的条目。我的搜索字符串看起来像“ test 123,其中有一个空格。我怎样才能在这个测试用例中获得成功?

我的 search-sql-query 看起来像:

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

result: 0 rows

所以我试图弄清楚是否可以将 pg_trgm 与 ts_vector 结合使用,但我找不到解决方案。你有想法吗?

4

1 回答 1

7

正如有关解析的文档所述:

...plainto_tsquery 将无法识别其输入中的 tsquery 运算符、权重标签或前缀匹配标签...

plainto_tsquery并且phraseto_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, query
WHERE (test.tsv @@ search.query)

这假设该表具有预先生成tsv的数据类型列,tsquery而不是在每个查询上都创建它(这要慢得多)。PG12+ 支持生成的列,可以自动更新。

于 2018-07-20T01:32:12.713 回答