【问题标题】:Sort an activerecord result set by another array of ids按另一个 id 数组对 activerecord 结果集进行排序
【发布时间】:2015-10-25 08:42:36
【问题描述】:

如何根据另一个 id 数组排序这个 activerecord 结果集?

我对我的 activerecord 模型执行初始查询:

results = Foo.first(5)
results.each do |r| 
  #do some stuff initially with these records. 
  #5 records returned with ids: 1, 2, 3, 4, 5
end 

然后我做一些进一步的处理,得到另一个 id 数组:

desired_order_ids = [3,1,4,5,2]

我想按desired_order_ids id 数组指定的顺序按Foo.id 订购results。这该怎么做?实际上,上面的查询将检索 1000 条记录,所以我正在寻找最节省内存的方法来做到这一点?

【问题讨论】:

  • 最有效的方法是在数据库中进行排序,但您需要提供有关表格的更多信息,了解如何对数据进行排序以获得任何有意义的答案。
  • 我同意你的观点,但我不想写一篇文章来解释背后的故事,得出的结论是不能进行 db 排序。简而言之,我正在查询检索结果集,然后对该结果集执行一些统计回归分析,该分析将专门应用于该结果集并且无法提前知道(因此无法存储在数据库中)。也许有一种方法可以存储在数据库中,但我会说这是第一次让它工作。

标签: ruby-on-rails sorting


【解决方案1】:

这取决于您使用的 DBMS,但我认为这适用于大多数数据库:

Foo.all.order('id=3 desc, id=1 desc, id=4 desc, id=5 desc, id=2 desc')

您可以使用一种方法来构建传递给order 的参数,如下所示:

def order_string(field_name, arr)
  arr.map { |val| "#{field_name}=#{val} desc" }.join(', ')
end

然后这样称呼它:

Foo.all.order(order_string('id', [3, 1, 4, 5, 2]))

【讨论】:

  • 谢谢!正是我需要的!
【解决方案2】:

您是否需要最终结果为ActiveRecord::Relation?如果您可以转换为Array,这应该是最简单的解决方案:

desired_order_ids.map { |id| results[id - 1] }

另一个选项可能是:

results.sort_by { |result| desired_order_ids.index(result.id) }

【讨论】:

  • 我选择了这个答案,因为我能够利用内存中的现有结果集,而无需返回并再次访问数据库。谢谢
猜你喜欢
  • 2013-05-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-02
  • 1970-01-01
  • 2011-02-10
  • 1970-01-01
相关资源
最近更新 更多