Sphinx:具有某些字符的 PDO 异常
Sphinx: PDO exception with certain characters
我试图让 Sphinx 搜索服务器与 PDO 一起工作,但在特定情况下使用 MATCH() 函数时会触发语法错误。
例如:
在我的代码中,我将搜索查询拆分为 space,然后使用 |
(OR) 运算符将其连接起来。如果有人输入 test > 3
,在匹配函数中它将变成 (test | > | 3)
。这个组合触发一个:Syntax error or access violation: 1064 main_idx: syntax error, unexpected '|' near ' > | 3'
。我不认为这是一个转义问题,因为 >
字符不在转义列表中,即使你试图转义它,它也不起作用。这是我使用的 Sphinx 版本中的错误吗?还是我做错了什么?
我使用的是 Sphinx 2.2.11 版。它实际上是这张图片提供的 docker 实例:jamesrwhite/sphinx-alpine:2.2.11
PHP 版本是 7.2.
这是我的非工作代码:
$searchQuery = "SELECT * FROM main_idx WHERE MATCH(:search)";
$dbh = new PDO('mysql:host=127.0.0.1;port=9306', 'root', 'root');
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $dbh->prepare($searchQuery);
$stmt->bindValue('search', 'test | > | 3');
$stmt->execute();
如果我使用 MySQLi 扩展,相同的代码工作得很好。它也适用于 PDO 和 Sphinx 版本 2.2.6。 2.2.6 和 2.2.11 之间一定发生了某些变化。有人遇到过这个问题吗?
比如说你想做一个精确匹配我喜欢这样做我的精确匹配...
...WHERE MATCH(column) AGAINST('happy I am') AND column LIKE '%happy I am%';
这将保证我完全匹配我想要匹配的地方,就好像我没有包含 AND LIKE... 它会匹配快乐 OR I OR am
此行为是由此错误 http://sphinxsearch.com/bugs/view.php?id=2305 and this fix https://github.com/sphinxsearch/sphinx/commit/d9923f76c7724fa8d05a3d328e26a664799841b7 引起的。在之前的修订中 ' > | ' 得到了支持。
我们在 Manticore Search(Sphinx 的分支)将检查修复是否正确,如果不正确,我们将做出更好的修复。感谢您指出这一点。
同时您可以使用 http://sphinxsearch.com/downloads/archive/ or build manually from the latest revision which supports the syntax (https://github.com/sphinxsearch/sphinx/commit/f33fa667fbfd2031ff072354ade4b050649fbd4e)
中的 2.2.8
[更新]
修复是正确的。只要您没有规范,在以前的版本中不显示有关该错误的错误就是错误的。 charset_table 中的字符 (>)。要解决此问题,您可以将 > 添加到 charset_table,然后在搜索查询中将其转义,例如:
mysql> select * from idx_min where match('test | \> | a');
+------+---------+----------+-------+------+
| id | doc | group_id | color | size |
+------+---------+----------+-------+------+
| 7 | dog > < | 5 | red | 3 |
+------+---------+----------+-------+------+
1 row in set (0.00 sec)
mysql> select * from idx_min where match('test | \< | a');
+------+---------+----------+-------+------+
| id | doc | group_id | color | size |
+------+---------+----------+-------+------+
| 7 | dog > < | 5 | red | 3 |
+------+---------+----------+-------+------+
1 row in set (0.00 sec)
或
$stmt->bindValue('search', 'test | \< | a');
在 PDO 中。
虽然发现了一个小错误,但如果非规范字符不在 charset_table 中,它不会生成错误。例如。
mysql> select * from idx_min where match('test | j | a');
Empty set (0.00 sec)
即使 j 不在 charset_table 中也能正常工作。我已经在我们的错误跟踪器中提交了一个错误 https://github.com/manticoresoftware/manticoresearch/issues/156
再次感谢您帮助指出这一点。
我试图让 Sphinx 搜索服务器与 PDO 一起工作,但在特定情况下使用 MATCH() 函数时会触发语法错误。
例如:
在我的代码中,我将搜索查询拆分为 space,然后使用 |
(OR) 运算符将其连接起来。如果有人输入 test > 3
,在匹配函数中它将变成 (test | > | 3)
。这个组合触发一个:Syntax error or access violation: 1064 main_idx: syntax error, unexpected '|' near ' > | 3'
。我不认为这是一个转义问题,因为 >
字符不在转义列表中,即使你试图转义它,它也不起作用。这是我使用的 Sphinx 版本中的错误吗?还是我做错了什么?
我使用的是 Sphinx 2.2.11 版。它实际上是这张图片提供的 docker 实例:jamesrwhite/sphinx-alpine:2.2.11 PHP 版本是 7.2.
这是我的非工作代码:
$searchQuery = "SELECT * FROM main_idx WHERE MATCH(:search)";
$dbh = new PDO('mysql:host=127.0.0.1;port=9306', 'root', 'root');
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $dbh->prepare($searchQuery);
$stmt->bindValue('search', 'test | > | 3');
$stmt->execute();
如果我使用 MySQLi 扩展,相同的代码工作得很好。它也适用于 PDO 和 Sphinx 版本 2.2.6。 2.2.6 和 2.2.11 之间一定发生了某些变化。有人遇到过这个问题吗?
比如说你想做一个精确匹配我喜欢这样做我的精确匹配...
...WHERE MATCH(column) AGAINST('happy I am') AND column LIKE '%happy I am%';
这将保证我完全匹配我想要匹配的地方,就好像我没有包含 AND LIKE... 它会匹配快乐 OR I OR am
此行为是由此错误 http://sphinxsearch.com/bugs/view.php?id=2305 and this fix https://github.com/sphinxsearch/sphinx/commit/d9923f76c7724fa8d05a3d328e26a664799841b7 引起的。在之前的修订中 ' > | ' 得到了支持。 我们在 Manticore Search(Sphinx 的分支)将检查修复是否正确,如果不正确,我们将做出更好的修复。感谢您指出这一点。
同时您可以使用 http://sphinxsearch.com/downloads/archive/ or build manually from the latest revision which supports the syntax (https://github.com/sphinxsearch/sphinx/commit/f33fa667fbfd2031ff072354ade4b050649fbd4e)
中的 2.2.8[更新] 修复是正确的。只要您没有规范,在以前的版本中不显示有关该错误的错误就是错误的。 charset_table 中的字符 (>)。要解决此问题,您可以将 > 添加到 charset_table,然后在搜索查询中将其转义,例如:
mysql> select * from idx_min where match('test | \> | a');
+------+---------+----------+-------+------+
| id | doc | group_id | color | size |
+------+---------+----------+-------+------+
| 7 | dog > < | 5 | red | 3 |
+------+---------+----------+-------+------+
1 row in set (0.00 sec)
mysql> select * from idx_min where match('test | \< | a');
+------+---------+----------+-------+------+
| id | doc | group_id | color | size |
+------+---------+----------+-------+------+
| 7 | dog > < | 5 | red | 3 |
+------+---------+----------+-------+------+
1 row in set (0.00 sec)
或
$stmt->bindValue('search', 'test | \< | a');
在 PDO 中。
虽然发现了一个小错误,但如果非规范字符不在 charset_table 中,它不会生成错误。例如。
mysql> select * from idx_min where match('test | j | a');
Empty set (0.00 sec)
即使 j 不在 charset_table 中也能正常工作。我已经在我们的错误跟踪器中提交了一个错误 https://github.com/manticoresoftware/manticoresearch/issues/156 再次感谢您帮助指出这一点。