Magento: найшвидший спосіб оновити атрибут продукту


15

Я шукаю найшвидший і надійний метод для масового оновлення атрибутів. Нижче наведені методи, про які я знаю, але я не знаю, з якими мені слід йти.

$store_id = 0;
Mage::getSingleton('catalog/product_action')->updateAttributes(
    array($product_id),
    array('attribute_code' => $attribute_code),
    $store_id
);

або

$product->setData($attribute_code, 1234); 
$product->getResource()->saveAttribute($product, $attribute_code); 

Відповіді:


31

Найшвидший спосіб - це прямий вибір і вставлення / оновлення в базі даних, але це не найбезпечніше. Ви можете легко ламати речі.

Я використовую Mage::getSingleton('catalog/product_action')->updateAttributes(...)підхід.
Це швидко, ви можете використовувати його для масового оновлення атрибутів товару, ви можете оновити значення атрибутів для конкретного магазину.
Я думаю, це охоплює більшість необхідних випадків.


спасибі, Маріус, я очікував на твою відповідь, але твій останній творець модуля - kool
Deepak Mallah,

1
насправді це не найшвидший вибір ... перевірити мою відповідь нижче
Фр.

@Fra Як ваш метод швидший? Він передбачає load. що нічого, крім швидкого. Наприклад, у способі 2 перший рядок із завантаженням товару марний. Ви $productніде не використовуєте .
Маріус

@Fra. Коли ви спростовуєте чиюсь відповідь, це приємно зазначити причину. Що не так у моїй відповіді?
Маріус

1
Я можу сказати те саме, що й для вашої відповіді ... це не найшвидший шлях. прямі запити SQL - найшвидший спосіб. Я не думаю, що вашої причини недостатньо для того, щоб викликати спроби. Але ви маєте право на свою думку.
Маріус

27

Насправді є 3 способи оновити атрибут продукту, не зберігаючи повний продукт. Залежно від коду / вимог один може бути швидшим, ніж інший.

Спосіб 1:

$product = Mage::getModel('catalog/product')->load($product_id);
$resource = $product->getResource();

$product->setData($attribue_code, $value);
$resource->saveAttribute($product, $attribute_code);

Спосіб 2:

$updater = Mage::getSingleton('catalog/product_action');
$updater->updateAttributes(array($product_id), array( $attribute_code => $value), 0);

Спосіб 3: (найшвидший)

 $update_resource = Mage::getResourceSingleton('catalog/product_action');
 $update_resource->updateAttributes(array($product_id), array( $attribute_code => $value), 0);

Усі вищевикладені методи набагато швидші, що в будь-якому разі зберігають весь продукт, є основні відмінності в продуктивності

Method 1:

  • найшвидший, але вимагає, щоб ви завантажили товар.
  • це не запускає події повторного виведення (саме тому швидше)
  • він працює у фронтенді

Method 2:

  • дозволяє масово оновити продукт
    (ви можете передавати декілька продуктів і кілька атрибутів)
  • він запускає подію масових дій та відносно залежний реіндекс
  • це не працює у фронтенді

Method 3:

  • це як метод 2, але не викликає жодного іншого спостерігача / індексатора
    (тому це змішаний підхід між методом 1 і 2)

Спосіб 3 є більш гнучким у будь-якому випадку, вам доведеться перевстановити ці продукти / атрибути вручну. (для того, щоб оновлювати їх на фронті)
Це може бути корисно, якщо ви хочете швидко оновити багато продуктів, а потім подзвонити в реіндекс.
(якщо ви використовуєте метод 2, повторний вираз для кожного продукту викликається після оновлення, і ці кілька викликів роблять весь процес повільним)

Щоб вручну повторно встановити один продукт, перегляньте функції, передбачені Mage_Catalog_Model_Product_Flat_Indexer, такі як:

  • updateAttribute($attributeCode, $store = null, $productIds = null)
  • updateProduct($productIds, $store = null)
  • ...

4
завжди було б краще прокоментувати downvote ...
Фра

Лише невелика примітка, значення $ має бути кодом значення (ціле число), а не «текстовим» значенням, яке ви бачите у своєму інтерфейсі
Алі Альваш,

хммм цікаво. Спосіб 2 звучить чудово, тільки у вас немає контролю над «зворотним зв'язком», що вдалося, а що не? Спосіб 1 також хороший. Але коли я закінчую оновлення свого циклу над даними: чи можу я вручну натиснути реіндекс, можливо, щоб вирішити це для ідентифікаторів продукту particulr?
snh_nl

Дивно. використовуючи метод 2. Я отримую фільтр невідомої помилки за стовпцем `` `Виняток випаду: SQLSTATE [42S22]: стовпець не знайдено: 1054 Невідомий стовпець 'catalog_product_entity.value_id' у списку полів, запит: SELECT catalog_product_entity. value_idВІД catalog_product_entityЧОГО (entity_type_id = 4 AND attribute_id = '68 'AND entit_id = '29') `` `цього не очікував. Працює 1.9.3.2
snh_nl

1
Врятували мені години роботи.
dipole_moment

3

Оновлення

Я шукаю найшвидший і надійний метод для масового оновлення атрибутів

"Масове оновлення атрибутів" для атрибутів чи продуктів?

Подумайте, що оновлення декількох атрибутів відповідає за все, але для продуктів це може бути корисним ...

Якщо ви хочете оновити продукти з колекції, ви не повинні цього робити ...

foreach ($collection as $product) {
    $product->setSomeData(...);
    # not here
    $product->save();
}

Це дозволить відправити події, відновити пріцерули та індекси. При цьому ніякі події (і деякі інші речі) не пропускаються і проходять набагато швидше.

foreach ($collection as $product) {
    $product->setSomeData(...);
}
$collection->save();

Щоб уникнути оновлень прицілів, ви можете додати ...

$product->setIsMassupdate(true);

Щоб вимкнути / увімкнути повторне виведення на льоту, подивіться на це ... https://github.com/Flagbit/Magento-ChangeAttributeSet/commit/676f3af77fec880bc64333403675d183e8639fae

/**
 * Set indexer modes to manual
 */
private function _storeRealtimeIndexer()
{
    $collection = Mage::getSingleton('index/indexer')->getProcessesCollection();
    foreach ($collection as $process) {
        if($process->getMode() != Mage_Index_Model_Process::MODE_MANUAL){
            $this->_index[] = $process->getIndexerCode();
            $process->setData('mode', Mage_Index_Model_Process::MODE_MANUAL)->save();
        }
    }

}
/**
 * Restore indexer modes to realtime an reindex product data
 */
private function _restoreRealtimeIndexer()
{
    $reindexCodes = array(
        'catalog_product_attribute',
        'catalog_product_flat'
    );
    $indexer = Mage::getSingleton('index/indexer');
    foreach ($this->_index as $code) {
        $process = $indexer->getProcessByCode($code);
        if (in_array($code, $reindexCodes)) {
            $process->reindexAll();
        }
        $process->setData('mode', Mage_Index_Model_Process::MODE_REAL_TIME)->save();
    }
}

А також промивання кешу перед масовим оновленням (продуктом) може підвищити продуктивність ...

Mage::app()->getCacheInstance()->flush();

Деякі номери від налагодження тут: https://github.com/Flagbit/Magento-ChangeAttributeSet/isissue/16


Mage::getSingleton('catalog/product_action')->updateAttributes(...) Здається, це не найшвидший метод ... принаймні, не з налаштуванням мутлістору та включеними плоскими таблицями ...

  • saveAttribute()

    $product = Mage::getModel('catalog/product')->load($productId);
    $resource = $product->getResource();
    $product->setData($attributeCode, $attributeValue);
    $resource->saveAttribute($product, $attributeCode);
    • Всього в т.ч. Час стіни (мікросек.): 437 787 мікросекунд
    • Всього в т.ч. ЦП (мікросекунди): 423 600 мікросекунд
    • Всього в т.ч. MemUse (байти): 4,433,848 байт
    • Всього в т.ч. PeakMemUse (байти): 4,395,128 байт
    • Кількість функціональних дзвінків: 25,711
  • updateAttributes()

    Mage::getSingleton('catalog/product_action')->updateAttributes(
        array($productId),
        array($attributeCode => $attributeValue),
        $storeId
    );
    • Всього в т.ч. Час стіни (мікросекція): 3 676 950 мікросекунд
    • Всього в т.ч. CPU (мікросекунди): 3,122,064 мікросекунди
    • Всього в т.ч. MemUse (байти): 8,174,792 байт
    • Всього в т.ч. PeakMemUse (байти): 8,199,192 байт
    • Кількість функціональних дзвінків: 150,132
  • updateAttributes() (ресурс одиночний)

    Mage::getResourceSingleton('catalog/product_action')->updateAttributes(
        array($productId),
        array( $attributeCode => $attributeValue),
        $storeId
    );
    • Всього в т.ч. Час стіни (мікросекція): 94155 мікросекунд
    • Всього в т.ч. Процесор (мікросекунди): 48,568 мікросекунд
    • Всього в т.ч. MemUse (байти): 1426,304 байт
    • Всього в т.ч. PeakMemUse (байти): 1,370,456 байт
    • Кількість функціональних дзвінків: 2221

Ви можете переглянути мою відповідь, щоб зрозуміти, чому ця функція займає різні часи ...
Фракт

Якщо дані, що випадають, updateAttributes() (resource singleton)приймають фактичне значення адміністратора? або ідентифікатор випадаючого елемента? (чомусь ми завжди не отримуємо значення / порожнє значення за допомогою цього методу, тобто нічого не вибрано
snh_nl

@snh_nl, ви повинні використовувати ID - комами, відокремленими для атрибутів мультиселектора.
sv3n
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.