1

我有一个大小约为 50M 的 json 文件,大约 10k 条记录。我正在使用以下代码以编程方式插入 Joomla,它工作得很好,因为所有相关表都同时更新,例如 #_assets,但是代码运行速度非常慢:现在已经过去了大约 40 个小时,但只处理了大约 4k 篇文章。我可以以某种方式加快这个过程吗?

我确实知道,如果我确实插入#_content,#_tags等,它会快得多,但这种方法有一些我试图避免的琐碎并发症。

<?php
define( '_JEXEC', 1 );
define('JPATH_BASE', dirname(dirname(__FILE__)));
define( 'DS', DIRECTORY_SEPARATOR );

require_once (JPATH_BASE . DS . 'includes' . DS . 'defines.php');
require_once (JPATH_BASE . DS . 'includes' . DS . 'framework.php');
require_once (JPATH_BASE . DS . 'libraries' . DS . 'joomla' . DS . 'factory.php' );

define('JPATH_COMPONENT_ADMINISTRATOR', JPATH_BASE . DS . 'administrator' . DS . 'components' . DS . 'com_content');

$mainframe = JFactory::getApplication('site');

require_once (JPATH_ADMINISTRATOR.'/components/com_content/models/article.php');

$string = file_get_contents("items.json");
$json_str = json_decode($string, true);
foreach($json_str as $row){
$new_article = new ContentModelArticle();
    $data = array(
        'title' => $row['title'][0],
        'alias' => $row['alias'],
        'introtext' => $row['content'],
        'state' => 1,
        'catid' => 8,           /* don't hard code here! */
        'created' => $row['pdate'][0],
        'created_by' => 798,
        'created_by_alias' => $row['poster'][0],
        'publish_up' => $row['pdate'][0],
        'urls' => $row['urls'],
        'access' => 1,
        'metadata' => array(
            'tags' => $row['tags'],
            'robots' => "",
            'author' => implode(" ", $row['poster']),
            'rights' => "",
            'xreference' => "",            
        ),
    );
$new_article->save($data);
}
4

1 回答 1

0

如果您在 Joomla 中将其作为扩展程序运行,我建议您打开调试并查看其中Profile InformationJoomla! Debug Console以了解所有时间都花在了哪里。

你不是,所以剩下的就是扣除(因此可能有问题)。

  1. 您正在ContentModelArticle为每个插入加载,这意味着它不仅会创建和销毁每一行的模型类,还会创建和销毁每一行的表类。

  2. 如果这些都是插入,那么您不需要模型的所有开销(例如,首先检查文章是否存在)。

  3. 如果数据全部有效,您也不需要prepareTable()内容模型中的数据准备 ( ) 或check()内容表中的 。

如果您不需要加载一次,则为每篇文章JTable调用传入数组的表对象。save()这将运行更新资产跟踪的 , , 并完成bind()插入check()store()

所以,你可以试试这样的东西,我认为它会更快,不确定多少。

$contentTable = JTable::getInstance('Content', 'JTable', array());
foreach($json_str as $row){
    $data = array(
        'title' => $row['title'][0],
        'alias' => $row['alias'],
        'introtext' => $row['content'],
        'state' => 1,
        'catid' => 8,           /* don't hard code here! */
        'created' => $row['pdate'][0],
        'created_by' => 798,
        'created_by_alias' => $row['poster'][0],
        'publish_up' => $row['pdate'][0],
        'urls' => $row['urls'],
        'access' => 1,
        'metadata' => array(
        'tags' => $row['tags'],
        'robots' => "",
        'author' => implode(" ", $row['poster']),
        'rights' => "",
        'xreference' => "",            
    ),
    $contentTable->save($data);
}

*免责声明:这不是经过测试的代码,它只是在我的脑海中进入浏览器。

于 2013-06-30T00:01:07.287 回答