1

我们使用最初在 Joomla 中开发的 Concrete5 构建了一个站点。我们的工作是把所有东西都带过来,然后 Concrete5 化它。该网站的主要部分是大约 1200 个音频教学,每个教学具有不同的属性,例如主题、作者、程序、位置等。

某些教义可能分配了多个属性,例如多个关键字或主题。

我想对所有属性进行计数,以便访问者一目了然地看到某个作者有多少教义,或者有多少是关于特定主题的,即:

  • 道德 (20)
  • 恐惧 (42)
  • 感恩 (55)

结果证明,我的原始代码被偷听了太多,对于这么多的教导和这么多的属性来说不实用。基本上,我遍历了每个属性,并根据 PageList 计数查找了总计数。我们正在谈论每个页面加载的数百次查找。在这里打开缓存似乎没有帮助。

是否有任何其他策略已被证明可以成功地聚合大量页面上的属性计数?

这是供参考的网站: http: //everydayzen.org/teachings/

4

2 回答 2

1

我通常会说“不要直接访问数据库;使用 API”,但我认为您应该在这里使用数据库。

检查[Collection|File]SearchIndexAttributes表。(我不确定教义是文件还是页面。如果是页面,您需要通过仪表板中的作业定期重新索引它们。)查看索引表比加入最近的表要容易得多属性值表中的版本。一旦你看到那个表,你就可以在 SQL 中做一些简单的 GROUPing。

如果您想使用 API,您可以像现在一样批量执行,进行适当的计算,然后缓存它。

没有理由缓存不应该工作,但第一次命中(当缓存冷时)当然会占用全部时间。您应该缓存我的 IndexAttributes 想法(完整的表读取和循环并非微不足道),但至少使用冷缓存应该花费几分之一秒,而数百个页面列表调用可能需要 10 秒或更长时间。

于 2013-08-18T14:41:45.850 回答
1

我在 Concrete5 的工作网站上做了类似的事情,通过显示工作所属的每个部门的数量。

即 HR (32)、Sales (12) 等

这是从实现此功能的 Helper 中获取的代码(这只是包含的相关功能):

<?php
class JobHelper {
/**
* GetDepartmentJobsCount
* Returns array of Department names with job count based on input Pages
* @param Array(Pages) - Result of a PageList->getPages
* @return Array
*/
public function getDepartmentJobsCount($pages) {
    $depts = $this->getDepartments();
    $cj = $this->setCounts($depts);        
    $cj = $this->setAttributeCounts($cj, $pages,'job_department');
    return $cj;
}

/**
* GetDepartments
* Return all available Departments
* @return Array(Page)
*/
public function getDepartmentPages(){
    $pld = new PageList();
    $pld->filterByPath('/working-lv'); //the path that your Teachings all sit under
    $pld->setItemsPerPage(0);
    $res = $this->getPage();
    $depts = array();
    foreach($res as $jp){
        $depts[$jp->getCollectionName()] = $jp;
    }
    ksort($depts);
    return $depts;
}

/**
* PopulateCounts
* Returns array of page names and counts
* @param Array - Array to feed from
* @return Array
*/
public function setCounts($v){
    foreach($v as $w){
        $a[$w]['count'] = 0;
    }
    return $a;
} 

/**
* PopulateCounts
* Returns array of page names, with counts added from attribute, and paths
* @param Array - Array to add counts and paths in to
* @param Array(Pages) - Pages to run through
* @param String - Attribute to also add to counts
* @param String - Optional - Job Search parameter, leave blank to get Page URL
* @return Array
*/
public function setAttributeCounts($cj, $pages, $attr){
    foreach($pages as $p) {
        $pLoc = explode('|',$p->getAttribute($attr));  // Our pages could have multiple departments pipe separated
        foreach($pLoc as $locName){
            $cj[$locName]['count']++;
        }           
    }
    return $cj;
}

然后,您可以从 PageList 模板执行以下操作

$jh = Loader::helper('job');
$deptCounts = $jh->getDepartmentJobsCount($pages);
foreach($deptCounts as $dept => $data) { 
    echo $dept . '(' . $data['count] . ')';
}
于 2016-07-05T14:13:15.317 回答