cronjob: How to reindex only what is needed

What I know, the Index is something global, so a reindex always covers all Stores/Websites of one Magento.

But, Magento has some functionality you will like. While "update on Save" does the updates to index instant, the "manual update" puts the same "updates" into a queue, which you can trigger later.

For this, you will need to write your own shell script or cron job

    $pCollection = Mage::getSingleton('index/indexer')->getProcessesCollection();

    foreach ($pCollection as $process) {
        $process->indexEvents();
    }

I will not explain the basics of the process models, simply have a look at the indexEvents function, it takes the entries of the queue and updates them. But be careful, the URL Index can be a bit slow. But that's another problem.


What you want is to create a shell CLI script, and use that to determine if an index requires a re-index.

Have a look at the scripts in the shell folder (log.php will do fine) as an example on how to make such a script.

The script you create would then check the status of the index, and only re-index if it is in a status that requires indexing.

I generally create my custom shell scripts in a folder called /scripts, as I don't like to pollute the core folder shell with my custom code.

To this effect, I have an abstract class that I base all my scripts off, and it contains code that allows me to easily re-index indexers if they require indexing.

here is my abstract class:

/**
 * Abstracted functions for scripts
 *
 * @category    ProxiBlue
 * @package     Scripts
 * @author  Lucas van Staden ([email protected])
 * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
 *
 */
require_once dirname(__FILE__) . '/../shell/abstract.php';

class Mage_Shell_Scripts_Abstract extends Mage_Shell_Abstract {

    public $_doReindexFlag = false;

    public function run() {

        die('Please implement a run function inyour script');

    }
    /**
     * Get the category model
     * @return Object
     */
    public function getCatalogModel() {
        return Mage::getModel('catalog/category');
    }

    /**
     * Reindex given indexers.
     * Tests if indexer actually needs re-index, and is not in manual state before it does index.
     * 
     * @param array $reIndex 
     */
    public function reindex(array $reIndex) {

        foreach ($reIndex as $indexerId) {
            $process = $this->_getIndexer()->getProcessByCode($indexerId);
            if ($process->getStatus() == Mage_Index_Model_Process::STATUS_REQUIRE_REINDEX && $process->getMode() != Mage_Index_Model_Process::MODE_MANUAL) {
                try {
                    echo "Reindexing: " . $process->getIndexerCode();
                    $process->reindexEverything();
                } catch (Exception $e) {
                    mage::logException("{$indexer} Indexer had issues. {$e->getMessage()}");
                }
            }
        }
    }

    /**
     * Get Indexer instance
     *
     * @return Mage_Index_Model_Indexer
     */
    private function _getIndexer() {
        return Mage::getSingleton('index/indexer');
    }

    /**
     * Returns a list of cache types.
     * @return void
     */
    public function getInvalidateCache() {
        $invalidTypes = $this->_getInvalidatedTypes();
        $result = array();
        foreach($invalidTypes as $cache) {
            if ($cache->status == 1) {
                $result[] = $cache;
            }    
        }
        return $result;
    }

    /**
     * Gets a list of invalidated cache types that should be refreshed.
     * @return array Array of invalidated types.
     */
    private function _getInvalidatedTypes() {
        return Mage::getModel('core/cache')->getInvalidatedTypes();
        //return $this->_getCacheTypes();
    }

    /**
     * Gets Magento cache types.
     * @return
     */
    private function _getCacheTypes() {
        //return Mage::helper('core')->getCacheTypes();
        return Mage::getModel('core/cache')->getTypes();
    }

}

Then a class that is based off that, that calls a re-index, after some work was done.

require_once dirname(__FILE__) . '/abstract.php';

class Mage_Shell_setCategoryStatus extends Mage_Shell_Scripts_Abstract {

    public $_doReindexFlag = true;
    public function run() {

        /** code stripped out as not warrented for this answer **/

        if ($this->_doReindexFlag) {
            $this->reindex(array('catalog_product_flat',
                'catalog_category_flat',
                'catalog_category_product',
                'cataloginventory_stock',
                'catalogsearch_fulltext',
            ));
        }
    }

}

$shell = new Mage_Shell_setCategoryStatus();
$shell->run();

Tags:

Cron

Indexer