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


Как я могу выбрать случайную строку, используя красноречивый или свободно владеющий фреймворком Laravel?

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

Есть идеи?

Author: Auromius, 0000-00-00

10 answers

Ларавель>=5.2:

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

Ларавель 4.2.7-5.1:

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

Laravel 4.0-4.2.6:

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

Ларавель 3:

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

Проверить эта статья в случайных строках MySQL. Laravel 5.2 поддерживает это, для более старой версии нет лучшего решения, чем использование НЕОБРАБОТАННЫХ запросов.

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

Редактировать 2: Laravel 5.2, наконец, реализует функцию-оболочку для этого. Это называется В случайном порядке().

 390
Author: aebersold, 2016-08-08 18:10:57

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

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

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

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

 39
Author: manish, 2016-06-14 14:35:50

Tl;dr: В настоящее время это реализовано в Laravel, см. "правка 3" ниже.


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

  • Это не зависит от базы данных. например, SQLite и PostgreSQL используют RANDOM()
  • Что еще хуже, это решение больше не применимо, так как это изменение:

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


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

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();
 22
Author: Gras Double, 2018-07-02 03:03:12

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

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

User::orderBy(DB::raw('RAND()'))->get();
 15
Author: Teodor Talov, 2016-06-25 19:48:21

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

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

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

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

Posts::where_status(1)->order_by(DB::raw('RAND()'));
 8
Author: Bilal Gultekin, 2013-03-23 21:20:08

Для Laravel 5.2>=

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

inRandomOrder()

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

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

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

 6
Author: Manuel Azar, 2016-07-14 16:56:18

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

ModelName::inRandomOrder()->first();
 6
Author: simhumileco, 2018-07-24 13:37:14

В вашей модели добавьте это:

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();
 2
Author: Neto, 2015-07-14 01:21:24

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

 1
Author: ctf0, 2014-12-16 09:12:47

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

// 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(); 
 1
Author: Doc, 2016-06-24 08:14:52