2014-11-17 5 views
24

In L-4 es einfach ist:wie erhält zufällige Reihe Laravel-5

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

Aber jetzt in L-5 nicht ein einziges Verfahren in diesem Beitrag beschrieben arbeitet: Laravel - Eloquent or Fluent random row

Meine Ansicht Datei wird nur leer. Irgendwelche Ideen?

EDIT:

Gelöst: $ random_quote = Zitat :: orderByRaw ("RAND()") -> erste();

+0

Welche Code haben Sie versucht? Es funktioniert, wahrscheinlich haben Sie etwas verpasst –

+4

Dies ist übrigens sehr schlecht Leistung. – rmobis

+0

Können Sie eine Leistung teilen? Ich habe C. 30 000 berühmte Sprüche in der Datenbank ... – Peter

Antwort

33

diesen Arbeiten aber wahrscheinlich haben Sie nicht mit der rechten namespace, benutzen Sie einfach die use Anweisung an den Anfang Ihres class Namen wie folgt aus:

<?php namespace SomeNamespace; 

use App\Quotation; // Says "Quotation.php" is in "App" folder (By default in L-5.0) 

class someClass { 
    //... 
} 

Dann können Sie in Ihrem method etwas wie folgt verwenden:

// You may add: use DB; at the top to use DB instead of \DB 
$random_quote = Quotation::orderBy(\DB::raw('RAND()'))->first(); 

Oder diese:

$random_quote = Quotation::orderByRaw("RAND()")->first(); 
Update-

(Seit Laravel - 5.2):

$random_quote = Quotation::inRandomOrder()->first(); 
+2

Wir sollten zuerst() statt get() Ich druckte Zeichenfolge, und die Variable war ein Array. Deshalb war die Ansicht leer. – Peter

+0

Sie sind willkommen :-) –

+0

'ORDER BY RAND()' ist eigentlich sehr langsam und ich meine wirklich, wirklich, ..., wirklich langsam. Ich merke schon auf einem Tisch mit 400 Reihen den Unterschied. – orustammanapov

11

Die orderByRaw ('RAND()') hat zwei Probleme:

  1. Es ist MySQL-Server abhängig
  2. Es kann auf große langsam Tabellen (holt alle Zeilen)

Hier ist die Lösung, die ich verwendet, die ein bisschen besser zu sein scheint:

$cnt = $records->count(); 
if ($cnt == 0) 
    return; 

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

EDIT: Bitte beachten Sie, dass meine Lösung ein Problem (Absturz wenn kein Glück) bei parallelen Anfragen an die Datenbank, wenn einige Datensätze zwischen den "count()" und "skip()" gelöscht werden.

10

UPDATE FÜR Laravel 5.3

Ich war glücklich, dies zu entdecken, ist jetzt ein nativer Abfrage-Funktion! : D

Die inRandomOrder Methode kann verwendet werden, um die Abfrageergebnisse nach dem Zufallsprinzip zu sortieren. Zum Beispiel können Sie diese Methode verwenden, um einen zufälligen Benutzer zu holen:

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

Leider keine dieser Antworten in vollem Umfang nutzen Laravel 5 Sammlungen. Wenn Sie wie ich von Google hierher gekommen sind und nach einer vollständig nativen Lösung suchen, schauen Sie bitte unten nach!

Die Antwort von The Alpha hat die Datenbank Abhängigkeitsfehler und Benjamins, wie er darauf hingewiesen, kann ein Problem darstellen, wenn Zeilen dazwischen entfernt werden. Sehr unwahrscheinlich, aber immer noch möglich.

Hier ist eine eine einzeilige Lösung zufällige Zeilen in Laravel 5+

// The setup 
$numberOfRows = 4; 
$models = Model::all(); // or use a ::where()->get(); 

// And the actual randomisation line 
$randRows = $models->shuffle()->slice(0,numberOfRows); 

Et voila wählen - glücklich Codierung! Stimme es ab, wenn du es siehst, damit es auf der Seite aufgeht :)

+4

Während dies definitiv funktionieren würde, ist es übertrieben, alle Ergebnisse einer Tabelle zu erhalten, wenn Sie nur eine Zeile wünschen. Wenn Sie sehr große Tabellen haben, würde dies die Leistung erheblich beeinträchtigen. –

+0

Verwenden Sie einfach ein -> Take (100)? –

+2

Dann würden Sie nur eine zufällige Zeile der ersten 100 Zeilen erhalten! –

8

Ich würde dies ein wenig anders umsetzen, mit Benjamin's idea. A Query Scope für diese fühlt sich angemessen, so dass es wiederverwendbar ist, und es fällt in Ihre normale Redewendung.

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

Ich werde ein Merkmal schaffen, die Modelle verwenden können, aber Sie können einfach die scopeRandom Methode direkt zu Ihrem Modell hinzufügen.

/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); 
    } 
} 

Dann wird jedes Modell Sie die globalen Bereiche nutzen wollen, nennen Sie die Eigenschaft in der Klasse.

/app/Quotation.php

<?php 

namespace App; 

use Illuminate\Database\Eloquent\Model; 

class Quotation extends Model 
{ 
    use GlobalScopes; 

    //... 
} 

Im Gebrauch:

$randomQuote = \Quotation::random()->first(); 
+1

Clevere Lösung und beste Laravel-spezifische Antwort auf dieser Seite. – mwallisch

3

In Laravel 5,1 (Laravel und 5.2) eine Methode in der randomCollection Klasse zurückgegeben durch der beredte Baumeister.

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

So Ihren Anruf

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

oder

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

sollte richtig funktionieren.

+3

'$ r = Zitat :: all() -> random (1);' funktioniert, aber es tut ein 'Select * aus Zitaten' zuerst was ... könnte ziemlich langsam sein, wenn es viele Zitate gibt ... – erapert

1
orderByRaw('RAND()') 

Hinweis: in ram alle Zeilen aus dem Rest der Abfrage nehmen, wenn Sie also einen großen Tisch whithout andere Filter in der gleichen Abfrage haben sie schlechte Leistungen geben, sonst ist dies Ihre Option

0

Laravel 5.4

1) bei Bedarf ein Zufallsmodell:

$object = Model::all()->random(); 

2), wenn viele zufällige Modelle benötigen:

$object = Model::all()->random($n); //$n - number of elements 
            //$object - collection 

Kommentar: Der Aufruf $ Kollektion-> random (1) wird nun zurückkehren ein neue Sammlungsinstanz mit einem Element. Diese Methode gibt nur ein einzelnes Objekt zurück, wenn keine Argumente angegeben werden.

Doc Ref: https://laravel.com/docs/5.4/collections#method-random