MySQL 全文搜索斯堪的纳维亚字符 ø æ
MySQL full text search for Scandinavian Characters ø æ
这是我能找到的关于这个主题的唯一 SO q/a,但它似乎没有回答问题:Fulltext search with nordic letters (æ, ø, å)
在 MySQL 我有一个用户叫 "John Nørbæk".
我希望在搜索时能够匹配该用户:
"Noerbaek"、"Nørbaek" 或 "Noerbæk"
(如果能够匹配 "Norbaek" 就好了,但我的谷歌搜索表明 ø 等同于 "oe" 而不是 "o" 所以现在感觉错误的要求)。
我正在使用utf8mb4_unicode_ci
我在这里创建了一个 SQL Fiddle:http://sqlfiddle.com/#!9/b5be3d4/3
我在网上得出的每个结果似乎都与 PHP 相关,并用 str_replace 替换这些字符,但如果我的数据库中的内容是 "Nørbæk" 那么那不是很有帮助。
我不能这样做,因为匹配的字符串需要在全文索引中:
SELECT * FROM users WHERE MATCH (REPLACE(`name`, 'æ', 'ae'))
AGAINST ('Nørbaek' IN BOOLEAN MODE);
这可行,但在搜索 "Michael" 之类的内容时当然会失败,因为它会被转换为 Michæl,所以这是不可能的。
SELECT * FROM users WHERE MATCH (`name`)
AGAINST (REPLACE('Nørbaek', 'ae', 'æ') IN BOOLEAN MODE);
所以我完全没有想法,必须有更好的方法来匹配这些字符吗?
我对可用性比其他任何事情都更感兴趣。
例如,如果一位年长的用户想要找到他们的 "Dr Nørbæk",他们需要能够输入一些内容才能找到他,而不是简单地被告知学习如何输入“ø”。
编辑 1:
一条评论建议我应该使用 utf8mb4_swedish_ci
但我的数据库中有来自各种语言的名称,包括中文,所以我认为我应该使用 utf8mb4_unicode_ci
尽管我会诚实地说我只是总是将 utf8mb4_unicode_ci
用作 "best practice" 而没有完全理解原因。
编辑 2:
一条评论建议 utf8_unicode_520_ci
,这似乎有效,如 fiddle 所示:http://sqlfiddle.com/#!9/6a604e/4 我将需要做更多的测试,看看它有什么其他影响。
正如约翰所展示的那样,
MATCH(col) AGAINST('Nørbæk' ...)
成功
IN BOOLEAN MODE
和 IN NATURAL LANGUAGE MODE
.
col = 'Norbaek'
,
Nørbæk
在 AGAINST
、 中的其他变体
- 5.6(可能是更高版本),
- 带排序规则
utf8_unicode_520_ci
(或 utf8mb4_unicode_520_ci
)。
http://mysql.rjweb.org/utf8_collations.html and http://mysql.rjweb.org/utf8mb4_collations.html 为任一字符集的 520 排序规则显示以下等效项 类:
A=a=ª=À=Á=Â=Ã=Ä=Å=à=á=â=ã=ä=å=Ā=ā=Ă=ă=Ą=ą
ae=Æ=æ
O=o=º=Ò=Ó=Ô=Õ=Ö=Ø=ò=ó=ô=õ=ö=ø=Ō=ō=Ŏ=ŏ=Ő=ő=Ơ=ơ
oe=Œ=œ
因此,鉴于该排序规则,没有必要执行 REPLACEs
;而是为列
指定排序规则(utf8_unicode_520_ci 或 utf8mb4_unicode_520_ci)
这是我能找到的关于这个主题的唯一 SO q/a,但它似乎没有回答问题:Fulltext search with nordic letters (æ, ø, å)
在 MySQL 我有一个用户叫 "John Nørbæk".
我希望在搜索时能够匹配该用户:
"Noerbaek"、"Nørbaek" 或 "Noerbæk"
(如果能够匹配 "Norbaek" 就好了,但我的谷歌搜索表明 ø 等同于 "oe" 而不是 "o" 所以现在感觉错误的要求)。
我正在使用utf8mb4_unicode_ci
我在这里创建了一个 SQL Fiddle:http://sqlfiddle.com/#!9/b5be3d4/3
我在网上得出的每个结果似乎都与 PHP 相关,并用 str_replace 替换这些字符,但如果我的数据库中的内容是 "Nørbæk" 那么那不是很有帮助。
我不能这样做,因为匹配的字符串需要在全文索引中:
SELECT * FROM users WHERE MATCH (REPLACE(`name`, 'æ', 'ae'))
AGAINST ('Nørbaek' IN BOOLEAN MODE);
这可行,但在搜索 "Michael" 之类的内容时当然会失败,因为它会被转换为 Michæl,所以这是不可能的。
SELECT * FROM users WHERE MATCH (`name`)
AGAINST (REPLACE('Nørbaek', 'ae', 'æ') IN BOOLEAN MODE);
所以我完全没有想法,必须有更好的方法来匹配这些字符吗?
我对可用性比其他任何事情都更感兴趣。
例如,如果一位年长的用户想要找到他们的 "Dr Nørbæk",他们需要能够输入一些内容才能找到他,而不是简单地被告知学习如何输入“ø”。
编辑 1:
一条评论建议我应该使用 utf8mb4_swedish_ci
但我的数据库中有来自各种语言的名称,包括中文,所以我认为我应该使用 utf8mb4_unicode_ci
尽管我会诚实地说我只是总是将 utf8mb4_unicode_ci
用作 "best practice" 而没有完全理解原因。
编辑 2:
一条评论建议 utf8_unicode_520_ci
,这似乎有效,如 fiddle 所示:http://sqlfiddle.com/#!9/6a604e/4 我将需要做更多的测试,看看它有什么其他影响。
正如约翰所展示的那样,
MATCH(col) AGAINST('Nørbæk' ...)
成功
IN BOOLEAN MODE
和IN NATURAL LANGUAGE MODE
.col = 'Norbaek'
,Nørbæk
在AGAINST
、 中的其他变体
- 5.6(可能是更高版本),
- 带排序规则
utf8_unicode_520_ci
(或utf8mb4_unicode_520_ci
)。
http://mysql.rjweb.org/utf8_collations.html and http://mysql.rjweb.org/utf8mb4_collations.html 为任一字符集的 520 排序规则显示以下等效项 类:
A=a=ª=À=Á=Â=Ã=Ä=Å=à=á=â=ã=ä=å=Ā=ā=Ă=ă=Ą=ą
ae=Æ=æ
O=o=º=Ò=Ó=Ô=Õ=Ö=Ø=ò=ó=ô=õ=ö=ø=Ō=ō=Ŏ=ŏ=Ő=ő=Ơ=ơ
oe=Œ=œ
因此,鉴于该排序规则,没有必要执行 REPLACEs
;而是为列