我有点陷入困境。我最近注意到,我的用户在搜索时输入的是国际语言字符。它完全把我的搜索算法搞砸了。在阅读了我下面的问题后,你能建议哪种单字节字符编码最适合支持在法语、德语、西班牙语等脚本类似英语的语言中进行搜索吗?
我的设置
我的搜索是在一个完全索引的数据库上进行MySQL匹配,然后使用PHP Levenstein来进一步过滤行。MySQL数据库是ISO-8859-1
编码的,搜索是UTF-8
编码的(因为,我听说UTF-8是一个更好的字符集,它支持更多的国际字符。)
MySQL问题
搜索过程分为两步。关于如何处理这个问题,我无法得到一个明确的答案,即在哪个字符编码中设置我的数据库
截至目前,数据库处于ISO-8859-1
编码。对于数据库上的MATCH AGAINST
搜索,
- 我希望像
Amelie
这样的查询返回具有Amélie
的行。也就是说,支持对非本地键盘进行跨语言搜索 - 对于本机键盘,像
Amélie
这样的输入当然应该返回Amélie
。反之亦然(搜索这样做是很自然的!)
问题的下一部分是应用Levenstein函数来查看文本的紧密性。
Levenstein问题
让我们假设我已经为Amélie
成功地返回了Amelie
,类似地,为Amelie
成功地返回Amélie
。现在,下一个问题是,作为一个非母语法语的人(是的,那是法语),我希望我的Levenstein能给出1的距离,因为é
被e
取代了。
现在,由于我的API是UTF-8编码的。用户输入的Amélie
被API转换为UTF-8编码的字符串,如Am'u00e9lie
,然后在这方面进行levenstein是一件可怕的事情。因为,我得到它们之间的距离为6。但事实上,我希望他们是一样的,因为他们是完全一样的东西!
$distance = levenshtein("Amu00e9lie","Amélie",1,1,1) //outputs 6
- 并发症1:话虽如此,人们可以立即得出的结论是,DB应该将
Amélie
UTF-8编码为Amu00e9lie
,在这种情况下,距离将为0。(这表明我可能应该选择单字节字符集?在这种情况下,什么?) - 并发症2:不幸的是,这个建议不起作用,因为这样在DB上搜索
Amu00e9lie
就不会返回英文版Amuelie
摘要
我试着详细阐述我的问题。由此,DB获得了第一优先级。应该对其进行编码,以满足我在"MySQL问题"中列出的两个问题,并确保Levenstein以如上所述的"合理"方式保持该字符集。
此外,我面临的限制是,我无法访问MySQL的根目录。我认为这无关紧要,只是说说而已。
首先:您使用的字符编码(例如"Am'u00e9lie"
)不是"UTF-8"。它是ASCII,包含一个Javascript转义字符串。对这些字符串执行任何类型的搜索或比较都将是痛苦的。
您需要做的是将表(理想情况下,所有表)转换为MySQL utf8mb4
(或者,如果没有转换,则转换为utf8
)字符编码,并在该表中本地存储Unicode字符串。一旦你这样做了,搜索就会"正常工作"——也就是说,搜索name = 'Amelie'
就会找到'Amélie'
,反之亦然。