100+ times faster to update the products in Magento 2

100+_times_faster_to_update_the_products_in_Magento 2

Hello Everyone, this is Mo. In this blog, we are going to explain how to optimize the product save. So that it will speed up the save method 100 times or more. 

    It makes a huge difference if you save the whole product with every single attribute and run an indexer or if you only change the value of some attributes. All periodic scripts should be optimized to extend the user experience.

If we want to save the product attribute, for example, product price, you can do it in 2 different ways.

Method 1

This is the optimized version we set product attributes as already known with the updateAttributes()function, but we do not save the whole product. You can get a \Magento\Catalog\Model\ResourceModel\Product\Action object With it, we can call updateAttributes() only to save this changed attribute. 

This function takes three parameters as follows:

  • One is the entityId or the productId
  • attributeData contains the key-value pair of the attribute code and the attribute label.
  • The last parameter is the storeId for which the product has to be updated or saved.

Sample code:

<?php

namespace Mo\Product\Model;

use Magento\Framework\App\Helper\AbstractHelper;

use Magento\Catalog\Model\ResourceModel\Product\Action as ProductAction;

use Magento\Store\Model\StoreManagerInterface as StoreManagerInterface;

Use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory as ProductCollection;

use Magento\Framework\App\Helper\Context;

use Psr\Log\LoggerInterface;

class Data extends AbstractHelper

{

    /**
     * @var ProductAction
     */

    protected $productAction;

    /**
     * @var LoggerInterface
     */

    protected $logger;

    /**
     * @var StoreManagerInterface
     */

    protected $storeManager;

    /**
     * @var ProductCollection
     */

    protected $productCollection;

    /**
     * Data constructor.
     *
     * @param ProductAction $productAction
     * @param StoreManagerInterface $storeManagerInterface
     * @param LoggerInterface $logger
     * @param Context $context
     */

    public function __construct(

        ProductAction $productAction,

        StoreManagerInterface $storeManagerInterface,

        ProductCollection $productCollection,

        LoggerInterface $logger,

        Context $context

    )
    {

        $this->productAction = $productAction;

        $this->logger = $logger;

        $this->storeManager = $storeManagerInterface;

        $this->productCollection = $productCollection;

        parent::__construct($context);

    }

    /**
     * Set Price as 100 for the first product in the Specific Store
     */

    public function updateProductAttributes()

    {

        try {

            $updateAttributes["price"] = 100;

            /**
             * @var \Magento\Catalog\Model\ResourceModel\Product\Collection $collection
             */

            $collection = $this->_productCollection->create();

            if ($collection->getSize()) {

                $product = $collection->getFirstItem();

                $storeId = $this->_storeManager->getStore()->getId();

                $this->_productAction->updateAttributes([$product->getId()], $updateAttributes, $storeId);

            }

        } catch (\Exception $e) {

            $this->_logger->critical($e->getMessage());

        }

    }

}

?>

Method 2

This is the normal method of calling the save() function. You can get a \Magento\Catalog\Api\ProductRepositoryInterface Interface With it we can call save(). In this method, we have to send the complete product object as a parameter.

sample code:

<?php

namespace Mo\Product\Model;

use Magento\Framework\App\Helper\AbstractHelper;

use Magento\Catalog\Model\ProductRepository as ProductRepository;

use Magento\Framework\App\Helper\Context;

use Psr\Log\LoggerInterface;

class Data extends AbstractHelper

{

    /**
     * @var ProductRepository
     */

    protected $productRepository;

    /**
     * @var LoggerInterface
     */

    protected $logger;

    /**
     * Data constructor.
     *
     * @param ProductRepository $catalogProductRepository
     * @param LoggerInterface $logger
     * @param Context $context
     */

    public function __construct(
        ProductRepository $catalogProductRepository,
        LoggerInterface $logger,
        Context $context
    )
    {

        $this->productRepository = $catalogProductRepository;
        $this->logger = $logger;
        parent::__construct($context);

    }

    /**
     * Set Price as 100 for the specific
     * product
     */

    public function updateProductAttributes()

    {

        try {

            //get your productId say for example 1

            $productId = 1;
            $productData = $this->productRepository->getById($productId);
            $productData->setPrice("100");
            $this->productRepository->save($productData);

        } catch (\Exception $e) {

            $this->logger > critical($e->getMessage());

        }

    }

}

?>

Conclusion

    This article shows how to speed up product save and it is possible to only save attribute values. This is up to 100 times faster than saving the whole product.

Planning to create a new product type? Read our blog about New product type creation in Magento 2.

Thank you for reading. Are you fascinated to know more about Magento,
What are you waiting for? Check out the other blogs in the Magento section and
follow us through Youtube and Instagram to know more about us.

Post a Comment

0 Comments