如何将前缀匹配附加到 PostgreSQL 中的 tsquery

How to append prefix match to tsquery in PostgreSQL

我正在尝试利用 PostgreSQL 的全文搜索功能,特别是当用户输入某些搜索文本时,我想在假设最后一个词不完整的情况下向他显示结果。

为此,需要将“*”通配符附加到最后一个 tsquery 词位。例如。如果用户输入 "The fat ra" 则 tsquery 应该是 'fat' & 'ra':*.

如果我将通配符附加到输入字符串并使用 plainto_tsquery 函数对其进行解析,则通配符将被删除 plainto_tsquery("The fat ra" || ":*") => 'fat' & 'ra'.

to_tsquery函数手动构造一个tsquery需要对字符串进行大量修改(如trim空格等特殊字符,将空格替换为&字符)使函数接受它.

有更简单的方法吗?

您可以将 tsquery 中的最后一个词素转换为字符串,附加 ':*',然后将其转换回 tsquery,从而使它成为前缀匹配:

=> SELECT ((to_tsquery('foo <-> bar')::text || ':*')::tsquery);
      tsquery      
-------------------
 'foo' <-> 'bar':*

对于您的用例,您需要使用 <-> 而不是 & 来要求单词彼此相邻。这是它们的不同之处的演示:

=> SELECT 'foo bar baz' @@ tsquery('foo & baz');
 ?column? 
----------
 t
(1 row)

=> SELECT 'foo bar baz' @@ tsquery('foo <-> baz');
 ?column? 
----------
 f
(1 row)

phraseto_tsquery 可以很容易地指定许多必须彼此相邻的单词:

=> SELECT phraseto_tsquery('foo baz');
 phraseto_tsquery 
------------------
 'foo' <-> 'baz'

综合起来:

=> SELECT (phraseto_tsquery('The fat ra')::text || ':*')::tsquery;
     tsquery      
------------------
 'fat' <-> 'ra':*

根据您的需要,更简单的方法可能是直接使用字符串构建 tsquery,然后进行强制转换:

=> SELECT $$'fat' <-> 'ra':*$$::tsquery;
     tsquery      
------------------
 'fat' <-> 'ra':*