我正在尝试利用PostgreSQL的全文本搜索功能,特别是当用户键入某些搜索文本时,我希望在假设最后一个单词不完整的情况下显示他的结果。
为此,“ *”通配符必须附加到最后一个tsquery lexeme。例如。如果用户键入"The fat ra"
,则tsquery应该为'fat' & 'ra':*
。
如果我将whildcart附加到输入字符串中,并使用plainto_tsquery
函数进行解析,则会删除plainto_tsquery("The fat ra" || ":*") => 'fat' & 'ra'
的whildcard。
使用to_tsquery
函数手动构造tsquery要求对字符串进行大量修改(例如修剪空格和其他特殊字符,用&字符替换空格)以使该函数接受它。
有更简单的方法吗?
答案 0 :(得分:1)
您可以通过将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':*