Как я могу выбрать случайную строку с использованием «Красноречивого» или «Свободного» в рамках 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()'))
:
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 ();