我需要使用全文搜索来获取列中包含单词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 yes,thierry henry is good sportsman。”
2)如果$word从引号开始,例如'henry,我得到了一个错误:syntax error in tsquery: "'henry",尽管搜索字符串已经被脱逃。
我怎样才能解决这个问题?

最佳答案

默认的英语词典将标记您的数据,将'视为it-would-a-space。您可以使用ts_debug检查PostgreSQL/TStk将如何处理您的文本:

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当作一个单词,你必须:
创建自定义词典以处理带撇号的单词
或者在使用前去掉tsvectortsquery中的撇号。
我认为第二种选择是最简单的:
$sql = "SELECT * FROM mytable WHERE plainto_tsvector('english', replace(col, '''','')) @@ to_tsquery(replace(:word,'''',''));"

10-08 03:56