【发布时间】:2019-10-23 08:05:22
【问题描述】:
Ruby 和 Postgres 的排序略有不同,这在我的项目中造成了一些微妙的问题。有两个问题:重音字符和空格。看起来 Ruby 正在按 ASCII 顺序排序,而 Postgres 正在使用正确的 Unicode collation algorithm 进行排序。
Heroku Postgres 11.2。数据库排序规则为en_US.UTF-8。
psql (11.3, server 11.2 (Ubuntu 11.2-1.pgdg16.04+1))
...
=> select 'quia et' > 'qui qui';
?column?
----------
f
(1 row)
=> select 'quib' > 'qüia';
?column?
----------
t
(1 row)
Heroku 上的 Ruby 2.4.4。
Loading production environment (Rails 5.2.2.1)
[1] pry(main)> 'quia et' > 'qui qui'
=> true
[2] pry(main)> 'quib' > 'qüia'
=> false
[3] pry(main)> ENV['LANG']
=> "en_US.UTF-8"
我可以修复重音字符的处理,但我无法让 Ruby 正确处理空格。例如,这是它们对同一个列表进行排序的方式。
Postgres: ["hic et illum", "quia et ipsa", "qui qui non"]
Ruby: ["hic et illum", "qui qui non", "quia et ipsa"]
我试过icunicode gem:
array.sort_by {|s| s.unicode_sort_key}
这会处理重音字符,但不能正确处理空格。
如何让 Ruby 使用 Unicode 排序算法进行排序?
更新在Unicode® Technical Standard #10 中可以找到更全面的示例。这些顺序正确。
[
"di Silva Fred",
"diSilva Fred",
"disílva Fred",
"di Silva John",
"diSilva John",
"disílva John"
]
【问题讨论】:
-
也许可以试试icu4r?
-
@daxim 那是 11 岁。但我确实尝试过with
ffi-icufrom this answer。它似乎只是让算法的一部分正确,它不处理空格。["di Silva Fred", "di Silva John", "diSilva Fred", "disílva Fred", "diSilva John", "disílva John"]
标签: ruby postgresql unicode collation