从每个类别中选择一个的有效方法 - Rails

SRa*_*ack 5 ruby sql postgresql activerecord ruby-on-rails

我正在开发一个简单的应用程序来返回随机选择exercises,每个选择一个bodypart.

bodypart是模型enum上的索引列Exercise.DB是PostgreSQL.

以下实现了我想要的结果,但感觉非常低效(每次击中db一次bodypart):

BODYPARTS = %w(legs core chest back shoulders).freeze

@exercises = BODYPARTS.map do |bp|
  Exercise.public_send(bp).sample
end.shuffle
Run Code Online (Sandbox Code Playgroud)

因此,这给exercise每个随机bodypart,并在最后混合顺序.

我还可以将所有练习存储在内存中并从中选择; 但是,我想这会有可怕的扩展(目前只有十几个种子记录).

@exercises = Exercise.all

BODYPARTS.map do |bp|
  @exercises.select { |e| e[:bodypart] == bp }.sample
end.shuffle
Run Code Online (Sandbox Code Playgroud)

对这些进行基准测试表明该select方法在小范围内更有效:

Queries:            0.072902   0.020728   0.093630 (  0.088008)
Select:             0.000962   0.000225   0.001187 (  0.001113)
MrYoshiji's answer: 0.000072   0.000008   0.000080 (  0.000072)
Run Code Online (Sandbox Code Playgroud)

我的问题是,是否有一种有效的方法来实现这一输出,如果是,那么这种方法可能是什么样子.理想情况下,我想将其保留为单个数据库查询.

很高兴使用ActiveRecord或直接在SQL中撰写.任何想法都非常感激.

MrY*_*iji 3

根据我的评论,你应该能够做到(感谢 PostgreSQL 的DISTINCT ON):

Exercise.select('distinct on (bodypart) *')
        .order('bodypart, random()')
Run Code Online (Sandbox Code Playgroud)