LaravelフレームワークでEloquentまたはFluentを使用してランダムな行を選択するにはどうすればよいですか?
SQL を使用すると、RAND() による順序付けができることを知っています。ただし、最初のクエリの前にレコード数をカウントせずにランダムな行を取得したいと思います。
何か案は?
Laravel >= 5.2:
User::inRandomOrder()->get();
または特定の数のレコードを取得するには
// 5 indicates the number of records
User::inRandomOrder()->limit(5)->get();
// get one random record
User::inRandomOrder()->first();
またはコレクションにrandomメソッドを使用します。
User::all()->random();
User::all()->random(10); // The amount of items you wish to receive
ララベル 4.2.7 - 5.1:
User::orderByRaw("RAND()")->get();
ララベル 4.0 - 4.2.6:
User::orderBy(DB::raw('RAND()'))->get();
ララベル 3:
User::order_by(DB::raw('RAND()'))->get();
MySQL のランダム行に関するこの記事を確認してください。Laravel 5.2 はこれをサポートしています。古いバージョンでは、RAW クエリを使用するよりも優れたソリューションはありません。
編集 1: Double Gras で言及されているように、 orderBy() は、この変更以降、ASC または DESC 以外は許可しません。それに応じて回答を更新しました。
編集 2: Laravel 5.2 は最終的にこのためのラッパー関数を実装します。これはinRandomOrder()と呼ばれます。
これは問題なく動作します。
$model=Model::all()->random(1)->first();
random 関数の引数を変更して、複数のレコードを取得することもできます。
注: 最初にすべての行をフェッチしてからランダムな値を返すため、巨大なデータがある場合はお勧めしません。
tl;dr:最近では Laravel に実装されています。以下の「編集 3」を参照してください。
->orderBy(DB::raw('RAND()'))
悲しいことに、今日の時点で、提案されたソリューションにはいくつかの注意事項があります。
RANDOM()
さらに悪いことに、この変更以降、このソリューションは適用できなくなりました。
$direction = strtolower($direction) == 'asc' ? 'asc' : 'desc';
編集: orderByRaw()メソッドを使用できるようになりました: ->orderByRaw('RAND()')
. ただし、これはまだ DB に依存しません。
FWIW、CodeIgniter は特別なRANDOM
ソート方向を実装しており、クエリを作成するときに正しい文法に置き換えられます。また、実装もかなり簡単なようです。Laravelを改善する候補があるようです:)
更新: GitHub でのこれに関する問題と、保留中のプル リクエストです。
編集 2:追跡を切りましょう。Laravel 5.1.18 以降、クエリ ビルダーにマクロを追加できます。
use Illuminate\Database\Query\Builder;
Builder::macro('orderByRandom', function () {
$randomFunctions = [
'mysql' => 'RAND()',
'pgsql' => 'RANDOM()',
'sqlite' => 'RANDOM()',
'sqlsrv' => 'NEWID()',
];
$driver = $this->getConnection()->getDriverName();
return $this->orderByRaw($randomFunctions[$driver]);
});
使用法:
User::where('active', 1)->orderByRandom()->limit(10)->get();
DB::table('users')->where('active', 1)->orderByRandom()->limit(10)->get();
編集3:ついに!Laravel 5.2.33 (変更ログ、PR # 13642) 以降、ネイティブ メソッドを使用できますinRandomOrder()
。
User::where('active', 1)->inRandomOrder()->limit(10)->get();
DB::table('users')->where('active', 1)->inRandomOrder()->limit(10)->get();
Laravel 4 およびorder_by
5では、orderBy
したがって、次のようになります。
User::orderBy(DB::raw('RAND()'))->get();
Laravel 5.2 の場合 >=
雄弁な方法を使用します。
inRandomOrder()
inRandomOrder メソッドを使用して、クエリ結果をランダムに並べ替えることができます。たとえば、次のメソッドを使用してランダムなユーザーを取得できます。
$randomUser = DB::table('users')
->inRandomOrder()
->first();
ドキュメントから: https://laravel.com/docs/5.2/queries#ordering-grouping-limit-and-offset
次のように流暢で雄弁な order_by メソッドを使用することもできます。
Posts::where_status(1)->order_by(DB::raw(''),DB::raw('RAND()'));
これは少し変わった使い方ですが、うまくいきます。
編集:@Alexが言ったように、この使用法はよりクリーンで機能します:
Posts::where_status(1)->order_by(DB::raw('RAND()'));
私のプロジェクトの1つで雄弁にランダムな結果を得る方法は次のとおりです。
$products = Product::inRandomOrder()->limit(10);
10 - プルするランダム レコードの数。