47

User.find(:all, :order => "RANDOM()", :limit => 10)Rails 3で行った方法でした。

User.all(:order => "RANDOM()", :limit => 10)これはRails 4でできると思っていた方法ですが、それでも非推奨の警告が表示されます:

DEPRECATION WARNING: Relation#all is deprecated. If you want to eager-load a relation, you can call #load (e.g. `Post.where(published: true).load`). If you want to get an array of records from a relation, you can call #to_a (e.g. `Post.where(published: true).to_a`).
4

10 に答える 10

115

order代わりにandlimitメソッドを使用することをお勧めします。を取り除くことができますall

PostgreSQL および SQLite の場合:

User.order("RANDOM()").limit(10)

または MySQL の場合:

User.order("RAND()").limit(10)
于 2013-06-28T20:39:29.327 に答える
40

ランダム関数はデータベースによって異なる可能性があるため、次のコードを使用することをお勧めします。

User.offset(rand(User.count)).first

もちろん、これは 1 つのレコードだけを探している場合にのみ役立ちます。

それ以上取得したい場合は、次のようにすることができます。

User.offset(rand(User.count) - 10).limit(10)

これは、 rand がcount - 10- 10より大きい数値を返した場合に、10 レコードを確実に取得するためです。

常に 10 個の連続したレコードを取得することに注意してください。

于 2015-01-14T22:53:01.480 に答える
23

最良の解決策は、データベース内で実際にランダムに注文することだと思います。ただし、データベースから特定のランダム関数を回避する必要がある場合は、使用pluckしてshuffleアプローチできます。

1 つのレコードの場合:

User.find(User.pluck(:id).shuffle.first)

複数のレコードの場合:

User.where(id: User.pluck(:id).sample(10))
于 2016-02-07T16:22:59.407 に答える
13

チェーンできるので、これをスコープにすることをお勧めします。

class User < ActiveRecord::Base
  scope :random, -> { order(Arel::Nodes::NamedFunction.new('RANDOM', [])) }
end 

User.random.limit(10)
User.active.random.limit(10)
于 2016-06-16T21:03:31.273 に答える
-4

これが簡単な解決策です..現在、150万件を超えるレコードで使用しており、まともなパフォーマンスを得ています。最善の解決策は、1 つ以上のランダムなレコード セットをキャッシュし、必要な間隔でバックグラウンド ワーカーでそれらを更新することです。

作成されたrandom_records_helper.rbファイル:

module RandomRecordsHelper

 def random_user_ids(n)
    user_ids = []
    user_count = User.count
    n.times{user_ids << rand(1..user_count)}
    return user_ids
 end

コントローラーで:

@users = User.where(id: random_user_ids(10))

これは方法よりもはるかに高速です.order("RANDOM()").limit(10)。13 秒の読み込み時間が 500 ミリ秒に短縮されました。

于 2016-06-07T15:37:42.593 に答える