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();