how get random row laravel-5

前端 未结 9 658
花落未央
花落未央 2021-02-02 07:12

In L-4 it was simple:

$random_quote = Quotation::all()->random(1);

But now in L-5 not a single method described in this post is working: Lar

相关标签:
9条回答
  • 2021-02-02 07:13

    Update for Laravel 5.4

    New randomsorting in Laravel 5.4 ->inRandomOrder()->first()

    0 讨论(0)
  • 2021-02-02 07:17

    The orderByRaw('RAND()') has 2 issues:

    1. It's MySQL-server dependant
    2. It can be slow on large tables (fetches all rows)

    Here is the solution i used, which seems to be a bit better:

    $cnt = $records->count();
    if ($cnt == 0)
        return;
    
    $randIndex = rand(0, $cnt-1);
    $obj = $records->skip($randIndex)->take(1)->first();
    

    EDIT: Please note that my solution may be a problem (crash if no luck) in case of parrallel requests to the database, if some records are deleted between the "count()" and the "skip()".

    0 讨论(0)
  • 2021-02-02 07:22

    random() gives error in 5.2, so instead u can use inRandomOrder https://laravel.com/docs/5.2/queries#ordering-grouping-limit-and-offset ,

    and it works on Eloquent like

    Model::inRandomOrder()->first()
    
    0 讨论(0)
  • 2021-02-02 07:23

    I'd implement this a little differently, using Benjamin's idea. A Query Scope for this feels appropriate so it's reusable, and it falls into your normal Eloquent use.

    Note: In Eloquent 5.2, there is built in support for global scopes.

    I'm going to create a trait that models can utilize, but you can just add the scopeRandom method directly to your specific model.

    /app/GlobalScopes.php

    <?php
    
    namespace App;
    
    use Illuminate\Database\Eloquent\Model;
    
    trait GlobalScopes
    {
        public function scopeRandom($query){
            $totalRows = static::count() - 1;
            $skip = $totalRows > 0 ? mt_rand(0, $totalRows) : 0;
    
            return  $query->skip($skip)->take(1);
        }
    }
    

    Then, each model you want to utilize the global scopes, name the trait inside the class.

    /app/Quotation.php

    <?php
    
    namespace App;
    
    use Illuminate\Database\Eloquent\Model;
    
    class Quotation extends Model
    {
        use GlobalScopes;
    
        //...
    }
    

    In use:

    $randomQuote = \Quotation::random()->first();
    
    0 讨论(0)
  • 2021-02-02 07:30

    In Laravel 5.1 (and Laravel 5.2) there is a random method in the Collection class returned by the Eloquent builder.

    https://laravel.com/docs/5.1/collections#available-methods

    So your call

    $random_quote = Quotation::all()->random(1);
    

    or

    $random_quote = Quotation::where('column', 'value')->get()->random(1);
    

    should work properly.

    0 讨论(0)
  • 2021-02-02 07:31
    orderByRaw('RAND()')
    

    Note: It will take in ram all the rows from the rest of the query, so if you have a large table whithout other filters in the same query it will give bad performances, otherwise this is your option

    0 讨论(0)
提交回复
热议问题