È possibile scorrere le raccolte Magento con l'impaginazione in modo nativo?


21

Quello che intendo con questo è: c'è un modo per fare:

$collection = $model->getCollection();
foreach ($collection as $item) { 
    $item->doStuff();
}

In modo tale che anche se la raccolta avesse 100.000 righe, caricherà solo una pagina di righe alla volta da MySQL e le impaginerà magicamente dietro di te.

Da guardare Varien_Data_Collection_Db::load()non sembra possibile, ma volevo solo controllare. Sembra qualcosa che dovrebbe essere un'esigenza comune.

Risposte:


18

Dovresti davvero usare

Mage::getSingleton('core/resource_iterator')

a tal fine, in quanto esiste esclusivamente per i motivi di prestazione menzionati.

Altrimenti, puoi usare una soluzione leggermente meno elegante usando un loop con setPageSize- c'è un buon esempio qui, /programming/3786826/how-to-loop-a-magento-collection


1
SIR, siete un gentiluomo e uno studioso.
Kalenjordan,

+1 per setPageSizeperché è semantico.
Filwinkle

Un'altra cosa che ho capito è che la core/resource_iteratorsoluzione in realtà non impagina la query mysql. Carica l'intero set di risultati in una volta, ma poi ti dà una riga alla volta da gestire nel tuo codice PHP. Quindi evita errori di memoria all'interno di PHP, ma a un certo punto attiverà le dimensioni massime dei pacchetti mysql, se il set di risultati è molto grande. Penso che proverò a costruire un bel po 'astratto risorse_iteratore usandosetPageSize()
kalenjordan

Sì, l'ho quasi omesso alla ricerca di punti mwoar! Ha davvero lo scopo di caricare un singolo prodotto rispetto a una collezione impaginata. Ma dovrebbe servire come base su cui basarsi.
Ben Lessani - Sonassi,

Ho implementato un iteratore generico in batch che raggruppa le query in MySQL ma fornisce anche un callback di singoli elementi di raccolta. Curioso cosa ne pensi: gist.github.com/kalenjordan/5483065
kalenjordan

5

Concordo con Ben Lessani che è necessario utilizzare il core/iteratormodello di risorse per caricare grandi raccolte una riga alla volta, se possibile .

Tuttavia, ci sono delle limitazioni. Come spiegato in " addAttributeToSelect non funziona con core / resource_iterator? " Non funziona bene con i modelli EAV se è necessario includere valori dalle tabelle dei valori degli attributi.

E l'esempio collegato da StackOverflow non è in realtà così buono perché ripete la stessa query con LIMITespressioni diverse . Per query complesse questo potrebbe essere un problema di prestazioni, ma ancora più importante, otterrai duplicati se vengono aggiunte nuove righe in mezzo.

Un modo migliore per gestire le raccolte in blocchi consiste innanzitutto nel caricare tutti gli ID, quindi utilizzare questi ID come filtro per la raccolta paginata effettiva.

Semplice esempio di prodotti:

$ids = Mage::getModel('catalog/product')
    ->getCollection()
    ->getAllIds();

$page = 1;
do {
    $collection = Mage::getModel('catalog/product')
        ->getCollection()
        ->addIdFilter($ids)
        ->setPageSize(100)
        ->setCurPage($page);

    $results = $collection->load();

    // do stuff ......

    $page++;

} while ($results->count());
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.