2014-09-10 12 views
5

Voglio interrogare il mio modello Laravel usando eloquente per i risultati che potrebbero dover corrispondere ad alcune clausole where, quindi i numeri predefiniti take e skip.Ottieni il numero di righe in Eloquent di Laravel prima di utilizzare "take" e "salta"

Questo non è un problema in sé, ma devo anche conoscere il numero di righe che sono state trovate nella query prima di ridurre il set di risultati con take e skip, quindi il numero originale di corrispondenze che potrebbe essere ogni riga nella tabella se non vengono utilizzate clausole o alcune se viene utilizzata una delle due.

Quello che voglio fare potrebbe essere compiuto effettuando la query due volte, con la prima omissione di "->take($iDisplayLength)->skip($iDisplayStart)" alla fine e il conteggio, ma ciò sembra solo disordinato.

Qualche idea?

$contacts = Contact::where(function($query) use ($request) 
{ 

    if (!empty($request['firstname'])) { 
     $query->where(function($query) use ($request) 
     { 
      $query->where('firstname', 'LIKE', "%{$request['firstname']}%"); 

     }); 
    } 

    if (!empty($request['lastname'])) { 
     $query->where(function($query) use ($request) 
     { 
      $query->where('lastname', 'LIKE', "%{$request['lastname']}%"); 

     }); 
    }  

}) 
->take($iDisplayLength)->skip($iDisplayStart)->get(); 

$iTotalRecords = count($contacts); 
+0

Proprio chiama 'count' e' take() -> skip() -> get() ', che c'è di disordinato? –

+0

Come vuoi dire scusa? Sicuramente dovrei ripetere l'intero - $ contacts = Contact :: where (funzione ($ query) usare ($ request) .... - parte ogni volta? –

+0

No, non lo è. Controlla la mia risposta –

risposta

16

È possibile utilizzare count quindi get sulla stessa query.

E a proposito, tutta la tua query è un po 'complicata. Essa si traduce in qualcosa di simile:

select * from `contacts` where ((`firstname` like ?) and (`lastname` like ?)) limit X, Y 

Chiusura in where è usato per fare una query in questo modo, per esempio:

select * from table where (X or Y) and (A or B); 

Quindi, per riassumere avete bisogno di questo:

$query = Contact::query(); 

if (!empty($request['firstname'])) { 
    $query->where('firstname', 'like', "%{$request['firstname']}%"); 
} 

if (!empty($request['lastname'])) { 
    $query->where('lastname', 'like', "%{$request['lastname']}%"); 
} 

$count = $query->count(); 

$contacts = $query->take($iDisplayLength)->skip(iDisplayStart)->get(); 
+0

Grazie, ho capito anche questo: ho usato $ query = DB :: table ('contacts'), tuttavia, e tutto il resto lo stesso –

+2

Tuttavia il risultato è completamente diverso . Finisci con ar raggio di stdObjects invece di Eloquent Collection. –

+0

'$ query-> count' restituisce il risultato sbagliato in molti dei miei casi ... potrebbe essere dovuto a join o altro, ma non è sicuramente il modo di andare purtroppo ... – IceFire

4

La classe Collection offre una giunta e un metodo di conteggio che si può trarre vantaggio.

In primo luogo si vorrebbe ottenere l'insieme ..

$collection = $query->get(); 

allora si può ottenere il conteggio e la giunzione di esso.

$count = $collection->count(); 
$records = $collection->splice($iDisplayStart, $iDisplayLength); 

Questo potrebbe essere difficile sulle prestazioni perché si sta eseguendo la query per l'intera collezione di volta in volta, piuttosto che mettere un limite sulla query, quindi potrebbe essere utile per memorizzare nella cache la raccolta, se questa pagina sta per essere colpito spesso . Allo stesso tempo però, questo colpirà il database solo una volta, quindi è un po 'un trade off.

+0

Il post di cui sopra è molto più efficiente poiché consente di ottenere solo i risultati necessari da SQL. Ne risultano due query SQL (una per il conteggio e una per ottenere i risultati), ma è meglio che inserire risultati non necessari. – Loren

+0

Se è una query costosa che non restituisce molti risultati, sarebbe più veloce consentire a PHP di gestirla. Inoltre, se si utilizzano due query, è possibile ottenere informazioni errate se sono presenti anche istruzioni di inserimento/aggiornamento/eliminazione Entrambe le soluzioni dovrebbero essere considerate in base al caso d'uso – user3158900

Problemi correlati