Magento 1 – How to Reindex a Single Product

indexingmagento-1products-management

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.

Best Answer

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