cronjob:如何仅重新索引需要的内容


8

我们有一个服务器,上面有5个单独的商店。有些实际上是不活跃的。有些每天活跃。减少服务器负载。我们将索引从自动更改为手动。然后,我们每6小时设置一次cronjob。我找到了 足够 全部重新编制索引的示例

我们现在运行这样的东西:
Shop1:0 0,6,12,18 * * * php -f /shell/indexer.php reindexall
Shop2:0 1,7,13,19 * * * php -f /shell/indexer.php reindexall
等等,以避免重叠。

现在,闲置的商店也每6小时重新索引一次,不需要使用。有没有一种方法可以仅对cronjob所需的内容重新编制索引?

还是我们完全做错了?

Answers:


3

您需要创建一个shell CLI脚本,并使用该脚本来确定索引是否需要重新索引。

看一下shell文件夹中的脚本(log.php会做得很好)作为如何制作这样一个脚本的示例。

然后,您创建的脚本将检查索引的状态,并且仅在处于需要索引的状态时才重新索引。

我通常在一个名为/ scripts的文件夹中创建自定义外壳脚本,因为我不想用我的自定义代码污染核心文件夹外壳。

为此,我有一个抽象类,我将所有脚本作为基础,并且该类包含的代码使我可以在需要索引的情况下轻松地重新索引索引器。

这是我的抽象类:

/**
 * Abstracted functions for scripts
 *
 * @category    ProxiBlue
 * @package     Scripts
 * @author  Lucas van Staden (sales@proxiblue.com.au)
 * @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();
    }

}

然后,在完成一些工作之后,基于该类的类将调用重新索引。

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

我不得不说@Flyingmana给出的答案实际上比我自己的回答要聪明得多;)
ProxiBlue 2014年

6

我知道,索引是全球性的,因此,重新索引总是涵盖一个Magento的所有商店/网站。

但是,Magento具有一些您想要的功能。尽管“保存时更新”会立即更新索引,但“手动更新”会将相同的“更新”放入队列中,您可以稍后触发。

为此,您将需要编写自己的Shell脚本或cron作业

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

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

我不会解释流程模型的基础知识,只看一下indexEvents函数,它获取队列的条目并更新它们。但是请注意,URL索引可能会有点慢。但这是另一个问题。


1
有趣的解决方案,我不知道激活“手动更新”后会保存事件。这将仅允许索引更改的数据。
Andreas von Studnitz 2014年

0

要为进程重新编制索引,我们需要它们的ID。
对于默认的magento,有9个过程可以重新索引,编号为1到9。

$ids = array(1,2,3,4,5,6,7,8,9);

有时,自定义模块中的某些流程也需要重新编制索引我们需要将这些ID添加到我们现有的ID数组中,要知道该流程的ID,只需将鼠标悬停在您的每个流程中
admin panel-> System-> Index Management

您将获得一个URL:admin / process / some_id / ......此ID对应于进程

$ids = array(1,2,3,4,5,6,7,8,9,390,391,478);
foreach($ids as $id)
{
   //load each process through its id
   try
   {
      $process = Mage::getModel('index/process')->load($id);
      $process->reindexAll();
      echo "Indexing for Process ID # ".$id." Done<br />";
   }
   catch(Exception $e)
   {
      echo $e->getMessage();
   }
}

这没有回答我的问题,如何更改cronjob。这也重新索引了一切。我只想重新索引已更改的零件。
janw 2014年

0
<?php
// this loops through all indexes and processes those that say they require reindexing

include_once '../app/Mage.php';

$mageRunCode = isset ( $_SERVER ['MAGE_RUN_CODE'] ) ? $_SERVER ['MAGE_RUN_CODE'] : '';
$mageRunType = isset ( $_SERVER ['MAGE_RUN_TYPE'] ) ? $_SERVER ['MAGE_RUN_TYPE'] : 'store';

    $app = Mage::app ( $mageRunCode, $mageRunType );
    for($i=3; $i<=9; $i++){
        $process = Mage::getSingleton('index/indexer')->getProcessById($i);
        $state = $process->getStatus();
    //    echo '<pre>'.$process->getData('indexer_code').': '.htmlentities(print_r($process->getStatus(),true)).'</pre>';
        if($process->getStatus() == 'require_reindex'){
            $process->reindexEverything();
        }
    }
    ?>

0

我最喜欢阿米特·贝拉(Amit Bera)的答案-但进行了修改,将id放置在一个数组中,最重要的是安排了最流畅的操作。如果直接通过数字进行重新索引,则一个索引表可能导致另一个索引表无效。IE索引product_flat表,然后价格会导致产品flat表失效并需要重新索引。

<?php
// this loops through all indexes and processes those that say they require reindexing

include_once 'app/Mage.php';

$mageRunCode = isset ( $_SERVER ['MAGE_RUN_CODE'] ) ? $_SERVER ['MAGE_RUN_CODE'] : '';
$mageRunType = isset ( $_SERVER ['MAGE_RUN_TYPE'] ) ? $_SERVER ['MAGE_RUN_TYPE'] : 'store';

$app = Mage::app ( $mageRunCode, $mageRunType );

$ids = array(13,9,8,7,6,1,2,3,5,4);

foreach($ids as $id){
  $process = Mage::getSingleton('index/indexer')->getProcessById($id);
  $state = $process->getStatus();
//      echo '<pre>'.$process->getData('indexer_code').': '.htmlentities(print_r($process->getStatus(),true)).'</pre>';
  if($process->getStatus() == 'require_reindex'){
    $process->reindexEverything();
  }
}

2
仅供参考,其@jim回答不正确。
dh47 2015年

0

M1检查索引器状态

在根目录下运行以下命令以检查状态。

php shell/indexer.php --status

在根目录中的命令下面运行以检查索引器。

php shell/indexer.php info

cronjob:如何仅重新索引需要的内容。

Time php -f {magento file path}/shell/indexer.php --reindex {set indexer}

例如:我每6小时设置一次重新索引

*_6_*_*_* php -f /home/magento/public_html/shell/indexer.php --reindex catalogsearch_fulltex
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.