Magento: Cách nhanh nhất để cập nhật thuộc tính sản phẩm


15

Tôi đang tìm kiếm phương pháp nhanh nhất và đáng tin cậy để cập nhật thuộc tính hàng loạt. Dưới đây là những phương pháp mà tôi biết nhưng tôi không biết nên đi theo hướng nào.

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

hoặc là

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

Câu trả lời:


31

Cách nhanh nhất là chọn trực tiếp và chèn / cập nhật vào cơ sở dữ liệu, nhưng đó không phải là cách an toàn nhất. Bạn có thể dễ dàng phá vỡ mọi thứ.

Tôi sử dụng Mage::getSingleton('catalog/product_action')->updateAttributes(...)cách tiếp cận.
Thật nhanh chóng, bạn có thể sử dụng nó để cập nhật hàng loạt các thuộc tính sản phẩm, bạn có thể cập nhật một giá trị thuộc tính cho một cửa hàng cụ thể.
Tôi nghĩ rằng nó bao gồm hầu hết các trường hợp cần thiết.


cảm ơn marius tôi đã mong chờ câu trả lời của bạn, btw người tạo mô-đun cuối cùng của bạn là kool
Deepak Mallah

1
nó không thực sự là lựa chọn nhanh nhất ... kiểm tra câu trả lời của tôi dưới đây
Fra

@Fra Phương pháp của bạn nhanh hơn như thế nào? Nó liên quan load. bất cứ điều gì nhưng nhanh chóng. Ví dụ, trong phương pháp 2, dòng đầu tiên với tải sản phẩm là vô dụng. Bạn không sử dụng $productbất cứ nơi nào.
Marius

@Fra. Khi bạn hạ thấp câu trả lời của ai đó, đó là một điều tốt đẹp để nêu lý do. Có gì sai với câu trả lời của tôi?
Marius

1
Tôi có thể nói điều tương tự cho câu trả lời của bạn ... đó không phải là cách nhanh nhất. truy vấn SQL trực tiếp là cách nhanh nhất. Tôi không nghĩ rằng lý do của bạn là đủ để hạ thấp. Nhưng bạn có quyền với ý kiến ​​của bạn.
Marius

27

Trên thực tế, có 3 cách để cập nhật một thuộc tính trên sản phẩm mà không lưu toàn bộ sản phẩm. Tùy thuộc vào mã / yêu cầu người ta có thể nhanh hơn người kia.

Cách 1:

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

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

Cách 2:

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

Phương pháp 3: (nhanh nhất)

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

Tất cả các phương pháp trên nhanh hơn nhiều mà tiết kiệm toàn bộ sản phẩm dù sao cũng có một số khác biệt lớn về hiệu suất:

Method 1:

  • là nhanh nhất, nhưng yêu cầu bạn tải sản phẩm.
  • nó không kích hoạt sự kiện reindex (đó là lý do nhanh hơn)
  • nó hoạt động ở frontend

Method 2:

  • cho phép cập nhật số lượng lớn sản phẩm
    (bạn có thể vượt qua nhiều sản phẩm và nhiều thuộc tính)
  • nó kích hoạt sự kiện hành động đại chúng và reindex tương đối
  • nó không hoạt động ở frontend

Method 3:

  • nó giống như phương thức 2, nhưng không gọi bất kỳ người quan sát / người lập chỉ mục nào khác
    (vì vậy đây là cách tiếp cận hỗn hợp giữa phương pháp 1 và 2)

Phương pháp 3 là cách linh hoạt hơn dù sao bạn sẽ phải giới thiệu lại các sản phẩm / thuộc tính đó theo cách thủ công. (để cập nhật chúng trên frontend)
Có thể hữu ích nếu bạn muốn cập nhật nhiều sản phẩm nhanh chóng và sau đó gọi reindex ở cuối.
(nếu bạn sử dụng phương pháp 2, một reindex cho mỗi sản phẩm được gọi sau khi cập nhật và nhiều cuộc gọi này làm cho toàn bộ quá trình chậm lại)

Để reindex thủ công một sản phẩm, hãy xem các chức năng được cung cấp bởi Mage_Catalog_Model_ Productt_Flat_Indexer, chẳng hạn như:

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

4
sẽ tốt hơn nếu bình luận downvote ...
Fra

Chỉ cần một lưu ý nhỏ, giá trị $ phải là mã giá trị (số nguyên), không phải giá trị 'văn bản' bạn thấy trong giao diện của mình
Ali Alwash

hmmm thú vị Phương pháp 2 nghe có vẻ hay, chỉ có bạn không có kiểm soát về 'phản hồi' những gì đã thành công, những gì không? Cách 1 cũng tốt. Nhưng khi tôi cập nhật xong vòng lặp dữ liệu của mình: tôi có thể tự khởi động reindex để giải quyết vấn đề này cho id sản phẩm particulr không?
snh_nl

Lạ thật. sử dụng Phương pháp 2. Tôi đang nhận được một bộ lọc không xác định lỗi theo cột `` `Bị bắt ngoại lệ: SQLSTATE [42S22]: Không tìm thấy cột: 1054 Cột không xác định 'catalog_product_entity.value_id' trong 'danh sách trường', truy vấn là: CHỌN catalog_product_entity. value_idTỪ catalog_product_entityWHERE (entity_type_id = 4 AND property_id = '68 'AND entity_id = '29') `` `không mong đợi điều đó. Chạy vào ngày 1.9.3.2
snh_nl

1
Tiết kiệm cho tôi hàng giờ làm việc.
lưỡng cực_moment

3

Cập nhật

Tôi đang tìm kiếm phương pháp nhanh nhất và đáng tin cậy để cập nhật thuộc tính hàng loạt

"Cập nhật thuộc tính khối lượng" cho các thuộc tính hoặc sản phẩm?

Hãy nghĩ rằng việc cập nhật nhiều thuộc tính đã được trả lời, nhưng đối với các sản phẩm thì điều này có thể hữu ích ...

Nếu bạn muốn cập nhật sản phẩm từ bộ sưu tập, bạn không nên làm điều này ...

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

Điều này sẽ gửi các sự kiện, xây dựng lại các pricerules và chỉ số. Với điều này, không có sự kiện nào (và một số thứ khác) được bỏ qua và nhanh hơn rất nhiều.

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

Để tránh cập nhật đẹp hơn, bạn có thể thêm ...

$product->setIsMassupdate(true);

Để tắt / bật reindex một cách nhanh chóng, hãy xem điều này ... https://github.com/Flagbit/Magento-ChangeAttributionSet/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();
    }
}

Và cũng xóa bộ đệm trước khi cập nhật hàng loạt (sản phẩm) có thể tăng hiệu suất ...

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

Một số số từ gỡ lỗi ở đây: https://github.com/Flagbit/Magento-ChangeAttributionSet/issues/16


Mage::getSingleton('catalog/product_action')->updateAttributes(...) dường như không phải là phương pháp nhanh nhất ... ít nhất là không phải với thiết lập mutlistore và các bảng phẳng được bật ...

  • saveAttribute()

    $product = Mage::getModel('catalog/product')->load($productId);
    $resource = $product->getResource();
    $product->setData($attributeCode, $attributeValue);
    $resource->saveAttribute($product, $attributeCode);
    • Tổng số bao gồm Thời gian treo tường (microsec): 437.787 microsec
    • Tổng số bao gồm CPU (microsec): 423.600 microsec
    • Tổng số bao gồm MemUse (byte): 4,433,848 byte
    • Tổng số bao gồm PeakMemUse (byte): 4.395.128 byte
    • Số lượng cuộc gọi chức năng: 25.711
  • updateAttributes()

    Mage::getSingleton('catalog/product_action')->updateAttributes(
        array($productId),
        array($attributeCode => $attributeValue),
        $storeId
    );
    • Tổng số bao gồm Thời gian treo tường (microsec): 3.676.950 microsec
    • Tổng số bao gồm CPU (microsec): 3.122.064 microsec
    • Tổng số bao gồm MemUse (byte): 8,174,792 byte
    • Tổng số bao gồm PeakMemUse (byte): 8.199.192 byte
    • Số lượng cuộc gọi chức năng: 150.132
  • updateAttributes() (tài nguyên đơn)

    Mage::getResourceSingleton('catalog/product_action')->updateAttributes(
        array($productId),
        array( $attributeCode => $attributeValue),
        $storeId
    );
    • Tổng số bao gồm Thời gian treo tường (microsec): 94.155 microsec
    • Tổng số bao gồm CPU (microsec): 48.568 microsec
    • Tổng số bao gồm MemUse (byte): 1.426.304 byte
    • Tổng số bao gồm PeakMemUse (byte): 1,370,456 byte
    • Số lượng các cuộc gọi chức năng: 2.221

bạn có thể xem lại câu trả lời của tôi để hiểu lý do tại sao các chức năng đó mất nhiều thời gian khác nhau ...
Fra

Đối với dữ liệu thả xuống có updateAttributes() (resource singleton)mất giá trị quản trị viên thực tế? hoặc id của phần tử thả xuống? (bằng cách nào đó chúng tôi luôn không nhận được giá trị / giá trị trống bằng cách sử dụng phương thức này tức là không có gì được chọn
snh_nl

@snh_nl bạn phải sử dụng ID - dấu phẩy được phân tách cho các thuộc tính multiselect.
sv3n
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.