Большая коллекция продуктов и оптимизация


Я написал этот фрагмент кода. Этот метод принимает в качестве аргумента название и цену товара. Данные берутся из файла строка за строкой. Существует 20 тысяч строк, поэтому этот метод вызывается 20 тысяч раз. Каково ваше предложение по оптимизации этого кода? поскольку импорт занимает около 2,5 часов.

protected function saveProductPrice($singleProduct) {

        $productCollection = Mage::getModel('catalog/product')->getCollection()
            ->addAttributeToFilter('name', $singleProduct['PRODUCT_NUMBER'])
            ->getFirstItem();
        $websiteID = $this->determineStoreID((int)$singleProduct['ERP_PRICE_LIST_ID']);
        $productCollection->setWebsiteId($websiteID);
        $productCollection->setUrlKey(false);
        $productCollection->setStoreId($websiteID)
            ->setPrice($singleProduct['LIST_PRICE']);

        try {
            $productCollection->save($productCollection);
            echo $singleProduct['PRODUCT_NUMBER'] . " price updated and added to website " . $websiteID . "\n";
        } catch (Exception $ex) {
            Mage::logException($ex);
        }
        unset($productCollection);
    }
Author: Raphael at Digital Pianism, 2016-06-13

3 answers

Одна вещь, которая может многое изменить, - это ограничить размер вашей коллекции товаров , так как вы каждый раз получаете только первый товар.

Вместо:

$productCollection = Mage::getModel('catalog/product')->getCollection()
    ->addAttributeToFilter('name', $singleProduct['PRODUCT_NUMBER'])
    ->getFirstItem();

Я думаю, вам следует сделать:

 $productCollection = Mage::getModel('catalog/product')->getCollection()
    ->addAttributeToFilter('name', $singleProduct['PRODUCT_NUMBER'])
    ->setPageSize(1)
    ->getFirstItem();

Кроме того, не рекомендуется сохранять продукты в цикле . (Кстати, я не понимаю, почему вы передаете $productCollection в качестве аргумента методу save()).

Предложение, которое является способом быстрее, может заключаться в использовании saveAttribute метод:

$productCollection->setStoreId($websiteID)->setPrice($singleProduct['LIST_PRICE']);
$productCollection->getResource()->saveAttribute($productCollection, 'price');
 2
Author: Raphael at Digital Pianism, 2016-06-13 09:17:16

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

$collection = Mage::getModel('catalog/product')->getCollection()
    ->addAttributeToSelect('name');
$productsByName = array();
foreach ($collection as $product) {
    if (!isset($productsByName[$product->getName()])) {
        $productsByName[$product->getName()] = array();
    }
    $productsByName[$product->getName()][] = $product;
}

Я вижу, что вы также используете метод для получения идентификатора веб-сайта $this->determineStoreID((int)$singleProduct['ERP_PRICE_LIST_ID']);.
Я понятия не имею, как это работает, но вы можете загрузить веб-сайты заранее, используя тот же метод, что и для продуктов, и сделать сопоставление между $singleProduct['ERP_PRICE_LIST_ID'] и веб-сайтами.

Тогда все, что вам нужно сделать, это: Допустим, у вас есть $singleProduct с данными из вашего досье.

Сделайте это сейчас:

$name = $singleProduct['PRODUCT_NUMBER'];
if (isset($productsByName[$name])) {  //if the products with the name exists
    $newPrice = $singleProduct['LIST_PRICE'];
    $storeId = your custom logic to determine the store view id
    $productIds = array(); 
    foreach ($productsByName[$name] as $product) {
        $productIds[] = $product->getId();
    }
    Mage::getSingleton('catalog/product_action')->updateAttributes(
        $productIds, //bulk update all the products with the same name
        array('price' => $newPrice), //update only the price
        $storeId //update for only the store id you need.
    )
}

Следите за синтаксическими ошибками, я не тестировал код.

 3
Author: Marius, 2016-06-13 09:17:17

Вы можете использовать метод Mage::getSingleton('catalog/product_action')->updateAttributes(array of product id, array of attribute data,store id) для экономии цены продукта.

$data['price'] = 12; 
Mage::getSingleton('catalog/product_action')->updateAttributes(aary(1),$data,0);

Этот метод быстр по сравнению с методом сохранения продукта.

 0
Author: Mufaddal, 2016-06-13 09:14:31