Php 使用包含单引号的单词进行postgresql全文搜索时出现问题

Php 使用包含单引号的单词进行postgresql全文搜索时出现问题,php,postgresql,Php,Postgresql,我需要使用全文搜索来获取列中包含单词O'henry 我的代码: $word = "O'henry"; $sql = "SELECT * FROM mytable WHERE to_tsvector('english', col) @@ to_tsquery(:word) "; $sth = $db->prepare( $sql ); $sth->execute( array(":word"=>$word) ); 我有两个问题: 1) 此查询匹配包含单词O'henry

我需要使用全文搜索来获取列中包含单词
O'henry

我的代码:

$word = "O'henry";
$sql = "SELECT * FROM mytable WHERE to_tsvector('english', col) @@ to_tsquery(:word) ";

$sth = $db->prepare( $sql );
$sth->execute(
    array(":word"=>$word)
);
我有两个问题:

1) 此查询匹配包含单词
O'henry
的列,但也匹配包含以下内容的列,例如:“是的,thierry henry是优秀的运动员。”

2) 如果
$word
以引号开头,例如
'henry
,我得到一个错误:
tsquery中的语法错误:“'henry”
,尽管搜索字符串已经转义


如何解决此问题?

阅读文档后,我认为这是
to\u tsquery
所接受的字符串类型的限制。根据:

_tsquery的输入必须已经遵循 tsquery输入

tsquery输入规则已定义。根据给出的示例,引擎将每个输入字处理为单引号字符串,这将打断您的输入。作为一种解决方法,我在中找到了一个建议(用户试图正确地转义输入
'ksan
):

select *
from items
where to_tsvector(name) @@ to_tsquery(E'[\']ksan')
要将此应用于您的情况,您需要使用以下内容预先格式化您的输入:

$word = 'E' . str_replace("'", "[\']", $word);

默认的英语词典将标记您的数据,将
视为一个空格。您可以使用
ts\u debug
检查PostgreSQL/tsearch如何处理您的文本:

psql=# SELECT * FROM ts_debug('english','o''henry');
   alias   |   description   | token |  dictionaries  |  dictionary  | lexemes 
-----------+-----------------+-------+----------------+--------------+---------
 asciiword | Word, all ASCII | o     | {english_stem} | english_stem | {o}
 blank     | Space symbols   | '     | {}             |              | 
 asciiword | Word, all ASCII | henry | {english_stem} | english_stem | {henri}
(3 rows)
从这个输出可以清楚地看出,如果您想让postgres将
o'henry
视为一个单词,您必须:

  • 创建自定义词典以处理带撇号的单词
  • 或者在使用前从
    tsvector
    tsquery
    中去掉撇号
我认为第二种选择是最简单的:

$sql = "SELECT * FROM mytable WHERE plainto_tsvector('english', replace(col, '''','')) @@ to_tsquery(replace(:word,'''',''));"

您是否尝试过使用ph_escape_字符串?。非常感谢,这解决了2个问题(在我的问题中),但1)问题仍然存在。非常感谢,这解决了2个问题(在我的问题中),但1)问题仍然存在。您是否通过测试验证了这一点?据我所知,第一个问题是因为您的搜索词被分成两个字符串('O'和'henry'),这个新方法应该可以防止这种情况。是的,经过测试,这个查询:
。。。WHERE to_tsvector('english',col)@@to_tsquery(E'O[\']henry')
也与包含文本的列相匹配:
O这里的一些单词henry
Hm,我明白了。我会继续寻找解决方案,但基于一些悬而未决的问题,例如,我不太抱希望。你知道如何为它创建自定义词典吗?我已经有一个自定义的消除口音,所以它会很好地烘烤到它。