Laravel – Красноречивый или Свободный случайный ряд

Как я могу выбрать случайную строку с использованием «Красноречивого» или «Свободного» в рамках Laravel?

Я знаю, что с помощью SQL вы можете сделать заказ с помощью RAND (). Однако я хотел бы получить случайную строку, не делая подсчет количества записей до первоначального запроса.

Есть идеи?

Laravel> = 5,2:

User::inRandomOrder()->get(); 

Laravel 4.2.7 – 5.1:

 User::orderByRaw("RAND()")->get(); 

Laravel 4.0 – 4.2.6:

 User::orderBy(DB::raw('RAND()'))->get(); 

Laravel 3:

 User::order_by(DB::raw('RAND()'))->get(); 

Проверьте эту статью на случайных строках MySQL. Laravel 5.2 поддерживает это, для более старой версии нет лучшего решения, а затем с использованием запросов RAW .

edit 1: Как упоминалось Double Gras, orderBy () не разрешает ничего другого, кроме ASC или DESC с момента этого изменения. Я обновил свой ответ соответственно.

edit 2: Laravel 5.2, наконец, реализует для этого функцию обертки . Он называется inRandomOrder () .

Это работает отлично,

 $model=Model::all()->random(1); 

вы также можете изменить аргумент в случайной функции, чтобы получить более одной записи.

Примечание: не рекомендуется, если у вас есть огромные данные, так как сначала они будут извлекать все строки, а затем возвращать случайное значение.

К сожалению, на сегодняшний день существуют некоторые предостережения с предложением ->orderBy(DB::raw('RAND()')) :

  • Это не DB-агностик. например, SQLite и PostgreSQL используют RANDOM()
  • Хуже того, это решение больше не применимо, поскольку это изменение :

    $direction = strtolower($direction) == 'asc' ? 'asc' : 'desc';

Теперь вы можете использовать метод orderByRaw () : ->orderByRaw('RAND()') . Однако это все еще не DB-агностик.

FWIW, CodeIgniter реализует специальное направление сортировки RANDOM , которое при построении запроса заменяется правильной грамматикой. Также это довольно легко реализовать. Похоже, у нас есть кандидат на улучшение Laravel 🙂

update: вот вопрос об этом на GitHub и мой ожидающий запрос на pull .

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 ( changelog , PR # 13642 ) вы можете использовать собственный метод inRandomOrder() :

 User::where('active', 1)->inRandomOrder()->limit(10)->get(); DB::table('users')->where('active', 1)->inRandomOrder()->limit(10)->get(); 

В Laravel 4 и 5 orderBy заменяется orderBy

Итак, это должно быть:

 User::orderBy(DB::raw('RAND()'))->get(); 

Вы также можете использовать метод order_by с беглостью и красноречием, например:

 Posts::where_status(1)->order_by(DB::raw(''),DB::raw('RAND()')); 

Это немного странное использование, но работает.

Изменить: Как сказал @Alex, это использование чище, а также работает:

 Posts::where_status(1)->order_by(DB::raw('RAND()')); 

Для Laravel 5.2> =

используйте метод «Красноречивый»:

 inRandomOrder() 

Метод inRandomOrder может использоваться для сортировки результатов запроса случайным образом. Например, вы можете использовать этот метод для извлечения случайного пользователя:

 $randomUser = DB::table('users') ->inRandomOrder() ->first(); 

из документов: https://laravel.com/docs/5.2/queries#ordering-grouping-limit-and-offset

В вашей модели добавьте следующее:

 public function scopeRandomize($query, $limit = 3, $exclude = []) { $query = $query->whereRaw('RAND()<(SELECT ((?/COUNT(*))*10) FROM `products`)', [$limit])->orderByRaw('RAND()')->limit($limit); if (!empty($exclude)) { $query = $query->whereNotIn('id', $exclude); } return $query; } 

затем на маршруте / контроллере

 $data = YourModel::randomize(8)->get(); 

есть также whereRaw('RAND()') который делает то же самое, u может затем цепочка ->get() или ->first() или даже сходить с ума и добавить ->paginate(int)

У меня есть таблица с тысячами записей, поэтому мне нужно что-то быстро. Это мой код для псевдослучайной строки:

 // count all rows with flag active = 1 $count = MyModel::where('active', '=', '1')->count(); // get random id $random_id = rand(1, $count - 1); // get first record after random id $data = MyModel::where('active', '=', '1')->where('id', '>', $random_id)->take(1)->first(); 

Вы можете использовать:

 ModelName::inRandomOrder()->first(); 

Вы можете легко использовать эту команду // Вопрос: имя модели // возьмите 10 строк из db. В файлах тасования …

$ questions = Question :: orderByRaw ('RAND ()') -> take (10) -> get ();