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