10

I would like to reindex a single product after an update.

Now I use:

$product = Mage::getModel('catalog/product')->loadByAttribute('sku', 'foobar');
// edit something
$product->save();

$stockItem = Mage::getModel('cataloginventory/stock_item')->loadByProduct($product->getId());
$stockItem->setForceReindexRequired(true);

Mage::getSingleton('index/indexer')->processEntityAction(
    $stockItem,
    Mage_CatalogInventory_Model_Stock_Item::ENTITY,
    Mage_Index_Model_Event::TYPE_SAVE
);

$product
    ->setForceReindexRequired(true)
    ->setIsChangedCategories(true);

Mage::getSingleton('index/indexer')->processEntityAction(
    $product,
    Mage_Catalog_Model_Product::ENTITY,
    Mage_Index_Model_Event::TYPE_SAVE
);

But this doesn't work, any ideas?

PS: $product->getId() is existing and correct.

10

This works fine in Magento CE 1.6 and newer:

$event = Mage::getSingleton('index/indexer')->logEvent(
    $product,
    $product->getResource()->getType(),
    Mage_Index_Model_Event::TYPE_SAVE,
    false
);
Mage::getSingleton('index/indexer')
    ->getProcessByCode('catalog_url') // Adjust the indexer process code as needed
    ->setMode(Mage_Index_Model_Process::MODE_REAL_TIME)
    ->processEvent($event);

The available indexer codes can be viewed using the query:

SELECT indexer_code FROM index_process;

In a native Magento 1.7 there are:

+---------------------------+
| indexer_code              |
+---------------------------+
| cataloginventory_stock    |
| catalogsearch_fulltext    |
| catalog_category_flat     |
| catalog_category_product  |
| catalog_product_attribute |
| catalog_product_flat      |
| catalog_product_price     |
| catalog_url               |
| groupscatalog2_category   |
| groupscatalog2_product    |
| tag_summary               |
+---------------------------+

In Magento EE 1.13 it's different, there the indexer automatically picks up changed entities on each cron run (every minute).

UPDATE

The above answer is 100% correct anyway I think the below information can add something more.

  • If you need to change just few attributes values in a product and automatically update the relative index table you can use this function: Mage::getSingleton('catalog/product_action')->updateAttributes();

  • if you want to manage the reindex by your own use the resourse model instead: Mage::getResourceSingleton('catalog/product_action')->updateAttributes();

For example I use the following function to fast update only certain attributes in a product.

 public function updateProductAttribute($product_id, $arrayChanges, $reindex = true)
{
    if (!is_array($product_id)) {
        $product_id = array($product_id);
    }

    // ths should trigger all required reindex
    $update = Mage::getSingleton('catalog/product_action');
    // Update value
    if (!$reindex) {
        $update = Mage::getResourceSingleton('catalog/product_action');
    }

    $update->updateAttributes($product_id, $arrayChanges, 0);
}

Note:

If you need to change the same attribute/values couple in a group of products you can pass the whole array of product_ids

  • I'll copy user5973's comment here, because it will be deleted. @Vinai are you saying that EE 1.13+ does not have this performance issues when reindexing product related data? Where can we confirm that EE indexer automatically picks up changed entities and processes only those ones? – Fabian Blechschmidt Apr 2 '14 at 11:31
  • In EE 1.13 the indexer uses MySQL triggers to pick up any changes on a DB level and record the updated entity IDs in a changelog table. These changelogs are then processed via cronjobs. – Vinai May 9 '14 at 6:30
2

I presume you mean you want to reindex a product after you edit it in the admin ui. The easiest method is to just set the indexer mode to "update on save". You would have to do this for all the indexers related to products that you are using, probably including: Product Attributes, Product Prices, Product Flat Data, Category Products, Stock Status.

This will probably slow down product saving though.

Alternatively perhaps this link will help. Please see the comments as well as they describe how to update the stock as well. http://www.magentocommerce.com/answers/discussion/239/reindex-one-product-at-a-time/p1

2

Make sure you're not doing this on frontend nor upgrade scripts, and currently loaded store is "admin". Otherwise, $product->save() will not work at all. Check first, that saving a product has effect.

2

Besides @feversocial's answer also make sure that you have everything that is needed to be loaded on the product before calling $product->save() . Otherwise the saving can actually remove things from the product I have experienced the hard way.

Like saving the product without a SKU at all which then breaks all url rewrites and makes the entire site redirect to this product page :S :P

  • Good point, that's why I think is better to use catolog/product_action approach so you don't risk the above issue – Fra Mar 22 '18 at 7:46
1

I these information can be useful to understand the whole scenario a little better.

  • If you need to change just an attribute value and automatically update the relative index table you can use this function: Mage::getSingleton('catalog/product_action')->updateAttributes();

  • if you want to manage the reindex by your own use the resourse model instead: Mage::getResourceSingleton('catalog/product_action')->updateAttributes();

For example I use the following function to fast update only certain attributes in a product.

public function updateProductAttribute($product_id, $arrayChanges, $reindex = true)
{
    if (!is_array($product_id)) {
        $product_id = array($product_id);
    }

    // ths should trigger all required reindex
    $update = Mage::getSingleton('catalog/product_action');
    // Update value
    if (!$reindex) {
        $update = Mage::getResourceSingleton('catalog/product_action');
    }

    $update->updateAttributes($product_id, $arrayChanges, 0);
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.