เป็นไปได้ไหมที่จะเน้นย้ำการสะสม Magento ด้วยการให้เลขหน้า


21

สิ่งที่ฉันหมายถึงคือ - มีวิธีทำ:

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

ในลักษณะที่แม้ว่าคอลเลคชั่นจะมีแถว 100k แต่ก็จะโหลดหน้าแถวในเวลาเดียวจาก MySQL และให้เลขหน้าสำหรับคุณอย่างน่าอัศจรรย์เบื้องหลัง

จากการดูVarien_Data_Collection_Db::load()มันไม่ได้เป็นไปได้ แต่แค่ต้องการตรวจสอบ ดูเหมือนว่าสิ่งที่ควรเป็นความต้องการทั่วไป

คำตอบ:


18

คุณควรใช้จริงๆ

Mage::getSingleton('core/resource_iterator')

เพื่อจุดประสงค์นี้เนื่องจากมีเหตุผลด้านประสิทธิภาพที่คุณกล่าวถึงอย่างหมดจด

มิฉะนั้นคุณสามารถใช้โซลูชันที่สวยงามน้อยกว่าเล็กน้อยโดยใช้ลูปด้วยsetPageSize- มีตัวอย่างที่ดีที่นี่/programming/3786826/how-to-loop-a-magento-collection


1
คุณเซอร์เป็นสุภาพบุรุษและเป็นนักวิชาการ
kalenjordan

+1 setPageSizeเนื่องจากเป็นความหมาย
philwinkle

อีกสิ่งหนึ่งที่ฉันรู้คือว่าcore/resource_iteratorวิธีแก้ปัญหาไม่ได้แบ่งหน้าแบบสอบถาม mysql มันโหลดชุดผลลัพธ์ทั้งหมดพร้อมกัน แต่จากนั้นให้คุณจัดการแถวในแต่ละครั้งในโค้ด PHP ของคุณ ดังนั้นจะหลีกเลี่ยงความผิดพลาดของหน่วยความจำภายใน PHP แต่ในบางจุดมันจะทำให้ขนาดแพ็คเก็ต mysql สูงสุดถ้าชุดผลลัพธ์มีขนาดใหญ่มาก ฉันคิดว่าฉันจะลองและสร้าง resource_iterator chunked แบบนามธรรมที่ดีโดยใช้setPageSize()
kalenjordan

ใช่ฉันถูกละเว้นในการติดตามคะแนน mwoar! มันมุ่งเป้าไปที่การโหลดผลิตภัณฑ์เดียวกับคอลเลกชันหน้า แต่มันควรทำหน้าที่เป็นฐานในการต่อเติม
Ben Lessani - Sonassi

ฉันใช้ iterator แบบแบตช์ทั่วไปที่จับคู่แบบสอบถามกับ MySQL แต่ยังมีการเรียกกลับรายการคอลเลกชันแต่ละ อยากรู้ว่าคุณคิดอย่างไร: gist.github.com/kalenjordan/5483065
kalenjordan

5

ผมเห็นด้วยกับเบน Lessaniว่าคุณควรจะใช้core/iteratorรูปแบบการใช้ทรัพยากรในการโหลดคอลเลกชันขนาดใหญ่หนึ่งแถวในเวลาถ้าเป็นไปได้

อย่างไรก็ตามมีข้อ จำกัด ดังที่อธิบายไว้ใน " addAttributeToSelect ไม่ทำงานกับ core / resource_iterator? " มันใช้งานไม่ได้กับรุ่น EAV หากคุณต้องการรวมค่าจากตารางค่าแอตทริบิวต์

และตัวอย่างที่เชื่อมโยงจาก StackOverflow นั้นไม่ค่อยดีนักเพราะมันจะทำซ้ำแบบสอบถามเดียวกันที่มีLIMITนิพจน์ต่างกัน สำหรับข้อความค้นหาที่ซับซ้อนอาจเป็นปัญหาด้านประสิทธิภาพ แต่สิ่งที่สำคัญกว่านั้นคือคุณจะได้รับข้อมูลซ้ำหากมีการเพิ่มแถวใหม่ในระหว่างนั้น

วิธีที่ดีกว่าในการจัดการกับคอลเลกชันเป็นชิ้นแรกโหลดรหัสทั้งหมดจากนั้นใช้รหัสเหล่านี้เป็นตัวกรองสำหรับคอลเลกชันเพจที่แท้จริง

ตัวอย่างง่ายๆสำหรับผลิตภัณฑ์:

$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());
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.