具有多个绑定参数的MySQL UTF-8全文搜索

时间:2013-11-23 10:34:25

标签: php mysql character polish

我的查询显示如下:

SELECT advert_id
FROM oop_adverts
WHERE cat_down = :id 
  AND province = :province
  AND MATCH (location) AGAINST (:location);

实践中:

SELECT advert_id 
FROM oop_adverts 
WHERE cat_down = 3 
  AND province = 5 
  AND MATCH (location) AGAINST ('Krakow');

如果我尝试这个查询,mysql最终得到0结果。 问题是查询中的波兰语短语。当我将此查询替换为:

SELECT advert_id 
FROM oop_adverts 
WHERE cat_down = 3
    AND province = 5 
    AND MATCH (location) AGAINST ('Krakow') COLLATE utf8_unicode_ci;`

我得到了:

Syntax error or access violation: 1253 COLLATION 'utf8_unicode_ci' is not valid for CHARACTER SET 'binary''

我不知道我应该在脚本php和mysql中使用什么collat​​e。你能救我吗?

PS。对不起我的“最好的英语”兄弟。

2 个答案:

答案 0 :(得分:2)

表架构是什么?

我猜'location'被定义为二进制字符串,无法使用像utf8_unicode_ci这样的排序规则进行比较。 请阅读此处了解更多信息。

http://dev.mysql.com/doc/refman/5.0/en/charset-binary-collations.html

编辑:

告诉我们您的架构以获得进一步的帮助。不过尝试这样的事情:

SELECT advert_id 
FROM oop_adverts 
WHERE cat_down = 3 
  AND province = 5 
  AND MATCH (CONVERT(BINARY(location) USING utf8)) AGAINST ('Krakow');

答案 1 :(得分:1)

根据评论中的讨论进行编辑:

由于你的表方案看起来很好(就utf8而言),你在OP中给出的第一个代码示例是正确的(没有整理的那个),假设你已经得到了正确的数据库整理和连接本身 - 大多数可能你有超过50%的行中的广告位置Kraków,这就是你获得0行结果的原因。

如果您想要使用全文搜索,您必须始终记住如果表的全文索引包含50%的数据行中出现的关键字,匹配查询将忽略该关键字

因此,您可以在布尔模式下使用全文搜索来绕过50%的阈值。查看此处的文档MySQL Boolean Full-Text Searches

例如,如果表格中有3行,其中Kraków,Krakow和Warszawa为advert_location,则下面的查询将为您提供0行结果:

SELECT advert_id 
FROM oop_adverts 
WHERE MATCH(`advert_location`) AGAINST ('Kraków')

但是如果你使用布尔模式,你将获得2行结果:

SELECT advert_id 
FROM oop_adverts 
WHERE MATCH(`advert_location`) AGAINST ('Kraków' IN BOOLEAN MODE)

如果您希望匹配多个单词,可以使用“+”运算符(有关详细信息,请参阅上面链接的文档)。

SELECT advert_id 
FROM oop_adverts 
WHERE MATCH(`advert_location`,`advert_title`) AGAINST ('+Kraków' '+Search phrase' IN BOOLEAN MODE)

请注意,请记住使用包含的“+”运算符构造绑定参数,例如,如果您使用的是PHP,则可以这样做:

$query= "SELECT advert_id 
        FROM oop_adverts 
        WHERE MATCH(`advert_location`,`advert_title`) AGAINST (:location :title IN BOOLEAN MODE)";

$SQL=$db->prepare($query);                          
$SQL->bindValue(':location', '+'.$searched_location, PDO::PARAM_STR);
$SQL->bindValue(':title', '+'.$searched_title, PDO::PARAM_STR);