如何使重音不敏感的`MATCH() AGAINST()`句子?

How to make an accent insensitive `MATCH() AGAINST()` sentence?

我有一个名为 products 的 table,它有一个名为 namevarchar 列,编码为 latin1_swedish_ci

我正在尝试进行搜索查询,以便使用 MATCH() AGAINST() 句子 name 过滤产品,如下所示:

SELECT *
FROM products
WHERE MATCH(name) AGAINST('*search_string*' IN BOOLEAN MODE)

它在没有重音符号的情况下工作得很好,但是,如果我有一个名为 Colágeno 的产品并且搜索输入是 Colageno,查询将无法捕获该产品。

所以我尝试了 this SO answer 中显示的内容,但没有成功。

SELECT *
FROM products
WHERE MATCH(CONVERT(BINARY(name) USING utf8)) AGAINST('*Colageno*' IN BOOLEAN MODE)

我收到错误:

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CONVERT(BINARY(name) USING utf8)) AGAINST('*Colageno*' IN BOOLEAN MODE)' at line 3

我只想捕捉像á, é, í, ó, ú.

这样的特殊字符

提前致谢!

正如答案的作者所指出的,您可以使用 CONVERT(BINARY(name) USING utf8) 而不是 CONVERT(BINARY(name) USING utf8)

MySQL 在将 varchar 值转换为全文时已经将它们转换为二进制值。

您在创建索引时需要考虑到这一点,否则您最终将搜索二进制数据而不是 varchar 数据。

另一种解决方案是为您的 varchar 列使用某种排序规则,比方说 latin1_general_ci。这样,搜索将始终将数据转换为二进制数据(如果 varchar 列还不是二进制数据)并在索引中以字节形式查找它。

您可以阅读更多相关信息 here

已解决!

经过评论的讨论,我发现错误不在MATCH() AGAINST()语句中,因为它默认不区分变音符号。

所以问题与变音符号如何存储在 MySQL 中有关,在我的例子中,它们是这样存储的 COLÁGENO -> COLÃ<0x81>GENO。因此,有必要找出如何在不破坏 table.

的情况下正确保存波浪号

编码

我尝试通过在 phpmyadmin 中执行以下指令来更改编码:

ALTER TABLE products CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;

但是,性能没有变化。

然后我尝试通过将 DEFAULT CHARSET=latin1 更改为 DEFAULT CHARSET=utf8mb4 来更改导出的 table 文件中的编码,但结果也没有任何变化。

手动修改重音

我的另一个尝试是,一旦进行了编码更改,就可以通过波浪号 Á 对应的字符手动修改具有 Ã<0x81> 等字符的单元格。但遗憾的是,这似乎破坏了对 table 的查询(我仍然能够正常访问其他 table)。

所以我想到了 masterguru 在评论中所说的关于编码更改改变脚本连接到 table 的方式,显然当我手动修改一个字符以放置波浪号时,脚本继续访问 table。 table 使用之前的编码。

解决方案

脚本在 PHP 中,因此我必须找到该语言的解决方案。

我发现 this answer 是英文的,其中说明了如何在数据库中正确保存波浪号。为此,您必须编写...

mysqli_set_charset($connection, "utf8");

...这是在连接到数据库之后。最后,我不得不将数据库中的稀有字符更改为相应的波浪字符,以便 MATCH AGAINST 起作用,瞧!


非常感谢 masterguru、Triby 和 aeportugal 在评论中提供的帮助!

原文posthttps://es.whosebug.com/questions/511745/como-hacer-que-la-b%c3%basqueda-match-against-ignore-los-tildes-o-acentos