在产品集合上使用Magento的资源迭代器模型

时间:2011-09-14 16:41:04

标签: magento

我最近发现了以下关于在调用大型产品集合时使用Magento的资源迭代器模型以节省资源的文章 - http://www.fontis.com.au/blog/magento/loading-large-collections。但是,我发现很难弄清楚如何让它输出完全相同的数据。

所以,假设我使用以下内容获取完整的产品系列并输出sku:

$productCollection = Mage::getModel('catalog/product')->getCollection();
foreach($productCollection as $product){
    echo $product->getSku().',';
}

使用分析器,我看到这是使用1,154,480字节来处理。

现在使用资源迭代器模型如下:

function productCallback($args)
{
    $product = Mage::getModel('catalog/product');
        $product->setData($args['row']);
        echo $product->getSku().',';
}
$_productCollection = Mage::getModel('catalog/product')->getCollection();;
$_productCollection = Mage::getSingleton('core/resource_iterator')->walk($_productCollection->getSelect(), array('productCallback'));

这使用199,912个字节。获得相同的东西是非常不同的,只是sku的基本列表。

但我的问题是,例如,如果我想制作一个很好的样式列表的产品,并获得他们的图像,网址等,我以前会在$ productCollection上使用foreach循环,如第一个例子中所示:

foreach($_productCollection as $product){
echo $product->getSku().',';
};

但这不再适用。看起来当它通过回调时,它的作用与foreach循环相同,依次运行每个产品。

那么,我如何以与以前相同的格式恢复我的集合,所以它再次在foreach循环中工作?我是否需要将产品添加到阵列中?如果是这样,我该怎么做?

3 个答案:

答案 0 :(得分:2)

我想你可能会忽略这一点。当您不需要完整的面向对象的方法或记录数组并且可以使用数据库中的原始值时,资源迭代器很好。

要输出图像和价格等内容,您需要具有计算图像缩略图功能的产品对象实例,或折扣如何影响价格。此外,当产品对象加载时,它会触发各种事件,以便其他模块也可以进行修改,这也是Magento如此可扩展的部分原因。如果您担心内存使用或执行时间cache the product list block,请不要更改任何其他内容。

答案 1 :(得分:1)

@clockworkgeek - 你是对的。要添加到此,

$visibility = array(
                      Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH,
                      Mage_Catalog_Model_Product_Visibility::VISIBILITY_IN_CATALOG
                  );

$_productCollection = Mage::getResourceModel('reports/product_collection')
                              ->addAttributeToSelect('*')
                              ->addOrderedQty()
                              ->addAttributeToFilter('visibility', $visibility)
                              ->setOrder('ordered_qty', 'desc');

答案 2 :(得分:0)

问题是在不久前提出的,但我想补充一下,可以在回调函数中加载产品并获取所需的任何属性,并通过a将其存储在对象的受保护成员数组中公共方法。

例如,您可能拥有类似

的模型
class Company_Module_Model_Indexer_Entity_Product
     public function addToData($key, $data)
    {
        $this->_data[$key] = $data;
    }

然后在这个类的方法中你可以:

Mage::getSingleton('core/resource_iterator')->walk($products->getSelect(), array(
            function ($args) {
                $rowProduct = Mage::getModel('catalog/product')->setData($args['row']);
                $indexKey   = $rowProduct->getId();
                $product    = Mage::getModel('catalog/product')->load($rowProduct->getId());

                $args['invoker']->addToData($indexKey, [YOUR_DATA]);
            }
        ), array('invoker' => $this));