addAttributeToSelect не работает с core / resource_iterator?

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']);
}

В моем getLine()методе я получаю нет, nameно addFinalPrice()работает:

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
}

Те же проблемы с image, priceи любой другой атрибут.

PiTheNumber
источник

Ответы:

7

К сожалению, core/iteratorмодель ресурсов плохо работает с моделями EAV, потому что она напрямую работает с запросом и не использует никаких специфических функций коллекции.

Это то, что обычно происходит при загрузке коллекции EAV (я немного упросту):

  • выбрать базовые данные из таблицы сущностей (это то, $collection->getSelect()что
  • загрузить атрибуты из таблиц значений с помощью дополнительного запроса и добавить эти данные в каждую загруженную модель

Все это происходит в load()методе (посмотрите Mage_Eav_Model_Entity_Collection_Abstract::_loadAttributes(), хотите ли вы увидеть детали реализации)

Поскольку причиной использования итератора ресурсов обычно является то, что вы не хотите загружать все данные сразу, вы не можете использовать эту функцию разумным образом.

Вместо этого я попытался создать один запрос с объединениями, но вскоре столкнулся с проблемой, что MySQL «только» допускает 63 объединения за раз. Если вам нужно только несколько атрибутов, это может сработать для вас.

В противном случае лучше всего загружать и обрабатывать коллекцию в виде кусков следующим образом:

$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());
Фабиан Шменглер
источник
Я использовал итератор из-за проблемы ограничения памяти, но оказалось, что при использовании итератора здесь используется еще больше памяти. Я исправил это возвращение к нормальной коллекции и ini_set('memory_limit','512M');.
PiTheNumber
7

Вы должны использовать второй параметр, 'inner'как это:

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

См .: /programming/24614533/magento-collection-iterator-cannot-get-additional-attribute.

PiTheNumber
источник
Это решение JOIN, к которому я обращался. Хорошо, если вам нужно только несколько атрибутов, но не пытайтесь это сделатьaddAttributeToSelect('*')
Фабиан Шменглер
Используйте 'left', если вы хотите включить объекты, атрибут eav которых вообще не установлен.
Силиконрокстар