【问题标题】:Postgres sort vs. Ruby on Rails SortPostgres 排序与 Ruby on Rails 排序
【发布时间】:2016-07-26 09:58:07
【问题描述】:

最近我们不得不通过“分页”来支持我们的网络应用

来自我们数据库的 2 个不同模型(客户、查询)。


假设我们的页面大小为 5,

我们正在对“名字”进行排序。

因此我们以下所有的“排序”操作都将按名字排序


我们的流程使用 Sort 3 次:

  1. DB 排序 - 客户模型。 DB 返回 5 条记录。
  2. DB 排序 - 查询模型。 DB 返回 5 条记录。
  3. 将上述所有记录存储在一个数组中。
  4. Ruby 排序(使用 sort! 方法)- 按 FirstName 字段对上述 10 条记录进行排序。
  5. 将前 5 条记录呈现给客户端(排序后)。

我们的问题:

似乎 Postgres 排序和 Ruby 排序对字符串有很大的不同。

例如,Postgres 和 Ruby 对以下单词进行不同的排序。

  1. w1 = '客户 1'
  2. w2 = '客户 - 你好'

排序结果:

Postgres:w1,w2

Ruby:w2、w1(相反)。

它在于数字和破折号(-)字符的面部Ruby比较器与Postgres相反。


我们的问题只在于“字符串”的排序。

按日期/整数排序的行为相同(感谢上帝)。

有谁知道是否可以覆盖/配置 Ruby 的排序? 因此我们预期的 Array 排序结果将遵循 Postgres 排序的配置。

【问题讨论】:

  • 排序需要一个块,你可以随意排序。
  • 没有“Postgres 排序”之类的东西。 postgres 的排序方式几乎不依赖于在特定表/列上设置的排序规则。
  • PostgreSQL 使用操作系统排序规则进行排序。你在你的数据库中得到什么SHOW lc_collate;?这就是您需要的顺序。
  • @SergioTulentsev 不幸的是,这个特殊的错误赢得了我与它的所有斗争。我到处都这样做。有一次,我在 100 多名客户面前展示了一张幻灯片,上面写着“我们几乎没有做到最好”。
  • 我最喜欢的是“我受够了”,当“我吃饱了”(例如,我不能再吃东西了)的意思是:“受够了”的意思是“非常沮丧并且可以“别再忍受了”用美式英语。语言很有趣! @SergioTulentsev

标签: ruby-on-rails arrays ruby postgresql sorting


【解决方案1】:

看来您需要自定义排序。这可以通过创建自定义方法来比较 2 个字符以替换 sort 方法使用的默认 <=> 来实现。

您可以根据需要实现字符串之间的比较操作(我的可能不是更好,但至少它可以根据需要反转破折号和数字之间的比较)。

这是我的自定义比较方法示例:

def custom_compare(s1, s2)
  s1_array = s1.split("")
  s2_array = s2.split("")
  s1_array.each_with_index do |c1, i|
    c2 = s2_array[i]
    if c1 != c2
      if(c1 == "-" && c2 =~ /\d/ || c2 == "-" && c1 =~ /\d/)
        return c1 == "-" ? 1 : -1
      end
      return c1 <=> c2
    end
  end
  return 0
end

然后在红宝石排序中使用它:

["customer - hello", "customer 1"].sort!{|a, b| custom_compare(a, b)}
# => ["customer 1", "customer - hello"]

【讨论】:

  • 我已经在使用自定义排序了。按名称排序实际上是按:first_name,last_name 排序,Ruby 中相应的排序是自定义比较,再次按 first_name,last_name 排序。问题是 Ruby 对字符串的排序操作与 PostgresDB 不同。而且我不能覆盖每 2 个字符的每个比较..
  • 是的,因此您应该将sort 分解为它的比较操作,并更改它。我已经用custom_compare 方法更新了我的答案,我试图反转破折号和整数之间的比较
  • 我认为已经存在的东西需要大量计算。我的意思是其他人提到的所谓“排序排序”。使用您的方式,为了保证 Ruby 和我的数据库中的相同行为,我需要覆盖每 2 个字符之间的每个比较。最多 N 选择 2 个覆盖 ...
  • 如果它已经存在,它将是等效的。本机方法并不比您自己制作的方法更有效。我不是说我的custom_compare 是唯一的,我说你应该建立你的。
猜你喜欢
  • 2010-11-23
  • 1970-01-01
  • 1970-01-01
  • 2017-12-08
  • 2012-07-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多