8
public function run()
{
    $products = Mage::getModel('catalog/product')
            ->getCollection()
            ->addFinalPrice()
            ->addAttributeToSelect('name')

    Mage::getSingleton('core/resource_iterator')
            ->walk($products->getSelect()->limit(10), array(array($this, 'getLine')));

}

public function getLine($args)
{
    var_dump($args['row']);
}

In my getLine() method I get no name but addFinalPrice() works:

array(16) {
  ["entity_id"]=>
  string(2) "61"
  ["entity_type_id"]=>
  string(1) "4"
  ["attribute_set_id"]=>
  string(2) "10"
  ["type_id"]=>
  string(6) "simple"
  ["sku"]=>
  string(15) "50-F01010001-03"
  ["has_options"]=>
  string(1) "0"
  ["required_options"]=>
  string(1) "0"
  ["created_at"]=>
  string(19) "2011-07-05 18:30:48"
  ["updated_at"]=>
  string(19) "2014-09-04 07:34:21"
  ["indexed_price"]=>
  string(7) "14.5000"
  ["price"]=>
  string(7) "14.5000"
  ["final_price"]=>
  string(7) "14.5000"
  ["minimal_price"]=>
  string(7) "14.5000"
  ["min_price"]=>
  string(7) "14.5000"
  ["max_price"]=>
  string(7) "14.5000"
  ["tier_price"]=>
  NULL
}

Same problem with image, price and every other attribute.

7

Unfortunately the core/iterator resource model does not work well with EAV models, because it directly works with the query and does not use any of the collection specific features.

This is what usually happens when loading an EAV collection (I'll simplify a bit):

  • select basic data from the entity table (this is what $collection->getSelect() does
  • load the attributes from the value tables with an additional query and add this data to each loaded model

This all happens in the load() method (see Mage_Eav_Model_Entity_Collection_Abstract::_loadAttributes() if you want to see the implementation details)

Since the reason for using the resource iterator is usually that you don't want to load all data at once, you cannot use this feature in a reasonable way.

I tried to build a single query with joins instead, but soon ran into the problem that MySQL "only" allows 63 joins at a time. If you only need a few attributes, it might work for you, though.

Otherwise your best bet is to load and process the collection in chunks like this:

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

$page = 1;
do {
    $collection = Mage::getModel('catalog/product')
        ->getCollection()
        ->addIdFilter($ids)
        ->setPageSize(100)
        ->setPage($page);
    $results = $collection->load();
    // do stuff ...
    $page++;
} while ($results->count());
  • I used the iterator because of a memory limit problem but it turned out using the iterator here use even more memory. I fixed it be reverting to normal collection and ini_set('memory_limit','512M');. – PiTheNumber Jul 16 '15 at 15:11
7

You got to use the second parameter 'inner' like this:

$products = Mage::getModel('catalog/product')
     ->getCollection()
     ->addAttributeToSelect(array('name', 'image'), 'inner');

See: https://stackoverflow.com/questions/24614533/magento-collection-iterator-cannot-get-additional-attribute

  • This is the JOIN solution that I was refering to. Good if you only need a few attributes, but don't try it with addAttributeToSelect('*') – Fabian Schmengler Jul 16 '15 at 14:56
  • Use 'left' if you want to include entities where the eav attribute is not set at all. – siliconrockstar Mar 20 '18 at 4:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.