我有点不知所措。我最近注意到我的用户在搜索时输入的是国际语言字符。它完全搞砸了我的搜索算法。阅读我的以下问题后,您能否建议哪种单字节字符编码最适合支持使用类似于英语的脚本语言(如法语、德语、西类牙语等)进行搜索?
我的设置
我的搜索是在全索引数据库上进行 MySQL 匹配,然后是 PHP Levenshtein 以进一步过滤掉行。 MySQL 数据库是 ISO-8859-1
编码的,搜索是 UTF-8
编码的(因为,我听说 UTF-8 是一个更好的字符集,支持更多的国际字符。 )
MySQL 问题
搜索过程分为两步。关于如何解决我的数据库中设置哪种字符编码的问题,我无法得到明确的答案。
截至目前,数据库采用 ISO-8859-1
编码。对于数据库上的 MATCH AGAINST
搜索,
- 我想要像
Amelie
这样的查询返回带有Amélie
的行。也就是说,支持非本地键盘的跨语言搜索。 - 对于原生键盘,
Amélie
这样的输入当然应该返回Amélie
。正好与上述相反(搜索这样做是很自然的!)
问题的下一部分是应用 levenshtein 函数来查看文本的接近度。
编辑问题
让我们假设我已经知道如何为 Amélie
成功返回 Amelie
并且类似地为 Amelie
返回 Amélie
>。现在,下一个问题是,作为非法语母语者(是的,那是法语),我希望我的 levenshtein 给出 1 的距离,因为 é
被替换了使用 e
。
现在,因为我的 API 是 UTF-8 编码的。来自用户的输入,如 Amélie
被 API 转换为 UTF-8 编码的字符串,如 Am\u00e9lie
,然后在这上面进行编辑是一件很糟糕的事情。因为,我得到它们之间的距离为 6。但实际上,我希望它们是相同的,因为它们是完全相同的东西!
$distance = levenshtein("Amu00e9lie","Amélie",1,1,1) //outputs 6
- 并发症 1:话虽如此,可以立即得出的结论是数据库应该将
Amélie
UTF-8 编码为Amu00e9lie
,在这种情况下,距离为0.(这表明我可能应该选择单字节字符集?在这种情况下,什么?) - 并发症 2:不幸的是,该建议行不通,因为在数据库中搜索
Amu00e9lie
不会返回英文版Amuelie
。
总结
我已尝试完整阐述我的问题。由此看来,优先考虑DB。应该对其进行编码,以便满足我在“MySQL 问题”中列出的 2 个问题,然后确保 levenshtein 以如上所述的“明智”方式保留此字符集。
此外,我面临的限制是我无法访问 MySQL 的根目录。我认为没什么大不了的,只是说说而已。
最佳答案
首先:您使用的字符编码(例如,"Am\u00e9lie"
)不是“UTF-8”。它是 ASCII,包含一个 Javascript 转义字符串。对这些字符串执行任何类型的搜索或比较都会很痛苦。
您需要做的是将表(最好是您所有的表)转换为 MySQL utf8mb4
(或者,如果失败,则为 utf8
)字符编码,以及将 Unicode 字符串本地存储在该表中。完成此操作后,搜索将“正常工作”——也就是说,搜索 name = 'Amelie'
将找到 'Amélie'
,反之亦然。
关于php - 哪种字符编码最适合 levenshtein 和 MySQL Match?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38543540/