Magento: Cara tercepat untuk memperbarui atribut produk

15

Saya mencari metode tercepat dan andal untuk pembaruan atribut massal. Di bawah ini adalah metode yang saya ketahui tetapi saya tidak tahu harus ke mana.

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

atau

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

Jawaban:

31

Cara tercepat adalah melakukan pemilihan langsung dan memasukkan / memperbarui dalam database, tetapi itu bukan yang paling aman. Anda dapat dengan mudah memecahkan barang-barang.

Saya menggunakan Mage::getSingleton('catalog/product_action')->updateAttributes(...)pendekatan.
Cepat, Anda dapat menggunakannya untuk memperbarui atribut produk secara massal, Anda dapat memperbarui nilai atribut untuk toko tertentu.
Saya pikir itu mencakup sebagian besar kasus yang dibutuhkan.

Marius
sumber
terima kasih marius saya mengharapkan tanggapan Anda, btw pembuat modul utama Anda adalah kool
Deepak Mallah
1
sebenarnya bukan yang tercepat memilih ... periksa jawaban saya di bawah ini
Fra
@ Frra Bagaimana metode Anda lebih cepat? Itu melibatkan load. apa pun kecuali cepat. Misalnya, dalam metode 2, baris pertama dengan beban produk tidak berguna. Anda tidak menggunakan di $productmana pun.
Marius
@Fra. Ketika Anda menurunkan suara jawaban seseorang, itu adalah hal yang bagus untuk menyatakan alasannya. Apa yang salah dengan jawaban saya?
Marius
1
Saya bisa mengatakan hal yang sama untuk jawaban Anda ... itu bukan cara tercepat. query SQL langsung adalah cara tercepat. Saya tidak berpikir alasan Anda cukup untuk downvoting. Tetapi Anda berhak atas pendapat Anda.
Marius
27

Sebenarnya ada 3 cara untuk memperbarui atribut pada suatu produk tanpa menyimpan produk lengkap. Tergantung pada kode / persyaratan yang satu bisa lebih cepat dari yang lain.

Metode 1:

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

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

Metode 2:

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

Metode 3: (tercepat)

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

Semua metode di atas jauh lebih cepat yang menyelamatkan seluruh produk, namun ada beberapa perbedaan kinerja utama:

Method 1:

  • adalah yang tercepat, tetapi mengharuskan Anda memuat produk.
  • itu tidak memicu acara reindex (itu sebabnya lebih cepat)
  • ini bekerja di frontend

Method 2:

  • memungkinkan untuk memperbarui produk massal
    (Anda dapat melewati beberapa produk dan beberapa atribut)
  • itu memicu peristiwa aksi massa dan reindex yang relatif tergantung
  • itu tidak berfungsi di frontend

Method 3:

  • itu seperti metode 2, tetapi tidak memanggil pengamat / pengindeks lain
    (jadi itu adalah pendekatan campuran antara metode 1 dan 2)

Metode 3 adalah yang lebih fleksibel lagi pula Anda harus mengindeks ulang produk / atribut tersebut secara manual. (untuk memperbaruinya di frontend)
Ini mungkin berguna jika Anda ingin memperbarui banyak produk dengan cepat dan kemudian memanggil reindex di akhir.
(jika Anda menggunakan metode 2, pengindeksan kembali untuk setiap produk dipanggil setelah pembaruan dan beberapa panggilan ini membuat seluruh proses menjadi lambat)

Untuk mengindeks kembali secara manual satu produk, lihat fungsi-fungsi yang disediakan oleh Mage_Catalog_Model_Product_Flat_Indexer seperti:

  • updateAttribute($attributeCode, $store = null, $productIds = null)
  • updateProduct($productIds, $store = null)
  • ...
Fra
sumber
4
akan selalu lebih baik untuk berkomentar downvote ...
Fra
Hanya sebuah catatan kecil, nilai $ harus berupa kode nilai (integer), bukan nilai 'tekstual' yang Anda lihat di antarmuka Anda
Ali Alwash
hmmm menarik. Metode 2 terdengar hebat, hanya saja Anda tidak memiliki kendali atas 'umpan balik' apa yang berhasil, apa yang tidak? Metode 1 juga bagus. Tetapi ketika saya selesai memperbarui loop data saya: dapatkah saya menendang reindex secara manual untuk menyelesaikan masalah ini untuk id produk tertentu?
snh_nl
Aneh. menggunakan Metode 2. Saya mendapatkan kesalahan filter yang tidak diketahui berdasarkan kolom `` `Pengecualian yang tertangkap: SQLSTATE [42S22]: Kolom tidak ditemukan: 1054 Kolom tidak dikenal 'catalog_product_entity.value_id' dalam 'daftar bidang', permintaan adalah: SELECT catalog_product_entity. value_idDARI catalog_product_entityMANA (entity_type_id = 4 AND atribut_id = '68 'AND entitas_id = '29') `` `tidak mengharapkan itu. Berjalan pada 1.9.3.2
snh_nl
1
Menyelamatkan saya berjam-jam kerja.
dipole_moment
3

Memperbarui

Saya mencari metode tercepat dan andal untuk pembaruan atribut massal

"Pembaruan atribut massal" untuk atribut atau produk?

Berpikir memperbarui beberapa atribut sudah terjawab, tetapi untuk produk ini dapat bermanfaat ...

Jika Anda ingin memperbarui produk dari koleksi, jangan lakukan ini ...

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

Ini akan mengirimkan acara, membangun kembali pricerules dan indeks. Dengan ini tidak ada acara (dan beberapa hal lainnya) yang dilewati dan jauh lebih cepat.

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

Untuk menghindari pembaruan pricerule, Anda dapat menambahkan ...

$product->setIsMassupdate(true);

Untuk menonaktifkan / mengaktifkan pengindeksan ulang dengan cepat, lihat ini ... 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();
    }
}

Dan juga membersihkan cache sebelum pembaruan massal (produk) dapat meningkatkan kinerja ...

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

Beberapa angka dari debugging di sini: https://github.com/Flagbit/Magento-ChangeAttributeSet/issues/16


Mage::getSingleton('catalog/product_action')->updateAttributes(...) tampaknya bukan menjadi metode tercepat ... setidaknya tidak dengan pengaturan mutlistore dan tabel datar dihidupkan ...

  • saveAttribute()

    $product = Mage::getModel('catalog/product')->load($productId);
    $resource = $product->getResource();
    $product->setData($attributeCode, $attributeValue);
    $resource->saveAttribute($product, $attributeCode);
    • Total Termasuk Waktu Dinding (microsec): 437.787 microsecs
    • Total Termasuk CPU (mikrod): 423.600 mikrod
    • Total Termasuk MemUse (bytes): 4.433.848 bytes
    • Total Termasuk PeakMemUse (bytes): 4,395.128 byte
    • Jumlah Panggilan Fungsi: 25.711
  • updateAttributes()

    Mage::getSingleton('catalog/product_action')->updateAttributes(
        array($productId),
        array($attributeCode => $attributeValue),
        $storeId
    );
    • Total Termasuk Waktu Dinding (microsec): 3.676.950 microsecs
    • Total Termasuk CPU (microsecs): 3.122.064 microsecs
    • Total Termasuk MemUse (byte): 8,174.792 byte
    • Total Termasuk PeakMemUse (byte): 8,199,192 byte
    • Jumlah Panggilan Fungsi: 150.132
  • updateAttributes() (sumber daya tunggal)

    Mage::getResourceSingleton('catalog/product_action')->updateAttributes(
        array($productId),
        array( $attributeCode => $attributeValue),
        $storeId
    );
    • Total Termasuk Waktu Dinding (microsec): 94.155 microsecs
    • Total Termasuk CPU (microsecs): 48.568 microsecs
    • Total Termasuk MemUse (bytes): 1.426.304 bytes
    • Total Termasuk PeakMemUse (byte): 1,370,456 byte
    • Jumlah Panggilan Fungsi: 2.221
sv3n
sumber
Anda dapat meninjau jawaban saya untuk memahami mengapa fungsi tersebut membutuhkan waktu yang berbeda ...
Fra
Untuk data dropdown apakah updateAttributes() (resource singleton)mengambil nilai admin yang sebenarnya? atau id dari elemen dropdown? (entah bagaimana kita selalu mendapatkan nilai / nilai kosong menggunakan metode ini yaitu tidak ada yang dipilih
snh_nl
@ snh_nl Anda harus menggunakan ID - koma yang dipisahkan untuk atribut multiselect.
sv3n