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и любой другой атрибут.

Ответы:


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.


Это решение JOIN, к которому я обращался. Хорошо, если вам нужно только несколько атрибутов, но не пытайтесь это сделатьaddAttributeToSelect('*')
Фабиан Шменглер

Используйте 'left', если вы хотите включить объекты, атрибут eav которых вообще не установлен.
Силиконрокстар
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.