搜索代码优化 - CakePHP

时间:2013-08-28 13:06:07

标签: php search cakephp-2.0

我有一个包含文件列表的数据库(大约6000个文件)。所有这些文件都有一些链接到它们的附加细节(例如项目编号,部门,客户,评论,学科)。

虽然代码和搜索工作,但速度非常慢。使用两个术语进行简单搜索大约需要一分钟才能完成。

我的代码如下。我想知道的是,我该怎么做才能简化和优化我的搜索功能?

public function search() {
    $Terms = explode(' ',$this->request->data['KmFiles']['search']);
    $possible = 0;
    $Matches = array();
    foreach($Terms as $Term) {
        $Files = $this->KmFile->find('list',
            array(
                'conditions' => array(
                    'file_name LIKE' => '%' . $Term . '%'
                ),
                'fields' => array('id')
            )
        );
        $possible++;
        $Clients = $this->KmClient->find('list',
            array(
                'conditions' => array(
                    'clients LIKE' => '%' . $Term . '%'
                ),
                'fields' => array('km_file_id')
            )
        );
        $possible++;
        $Disciplines = $this->KmDiscipline->find('list',
            array(
                'conditions' => array(
                    'disciplines LIKE' => '%' . $Term . '%'
                ),
                'fields' => array('km_file_id')
            )
        );
        $possible++;
        $Projects = $this->KmProject->find('list',
            array(
                'conditions' => array(
                    'projects LIKE' => '%' . $Term . '%'
                ),
                'fields' => array('km_file_id')
            )
        );
        $possible++;
        $Sectors = $this->KmSector->find('list',
            array(
                'conditions' => array(
                    'sectors LIKE' => '%' . $Term . '%'
                ),
                'fields' => array('km_file_id')
            )
        );
        $possible++;
        $Comments = $this->KmComment->find('list',
            array(
                'conditions' => array(
                    'comments LIKE' => '%' . $Term . '%'
                ),
                'fields' => array('km_file_id')
            )
        );
        $possible++;
        $Matches = array_merge($Matches,$Files,$Clients,$Disciplines,$Projects,$Sectors,$Comments);
    }
    if(count($Matches) > 0) {
        $NumberOfMatches = array_count_values($Matches);
        $Matches = array_unique($Matches);
        $k=0;
        foreach($Matches as $Match) {
            $Result = $this->KmFile->find('all',
                array(
                    'conditions' => array(
                        'id' => $Match
                    )
                )
            );
        $Results[$k] = $Result[0];
        $Results[$k]['Relevance'] = round(($NumberOfMatches[$Match] / $possible) * 100,2);
        $relevance[] = $Results[$k]['Relevance'];
        $k++;
    }
        array_multisort($relevance,SORT_DESC,$Results);
        $Stats['Count'] = count($Results);
        $Stats['Terms'] = $this->request->data['KmFiles']['search'];
        $this->set(compact('Results','Stats'));
    } else {
        $Stats['Count'] = 0;
        $Stats['Terms'] = $this->request->data['KmFiles']['search'];
        $this->set(compact('Stats'));
    }
}

我知道这是一段很长的代码,但我是CakePHP的新手,所以不知道如何改进它。

任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

为了加快速度,你必须尽可能地推迟对数据库的责任(数据库现在真的很快!)并最小化PHP和数据库之间的来回。理想情况下,您只需在一次查询中获取所有搜索结果(即一次find次调用)。

您指定joins,以便您的KmFile模型与您的KmClient,KmProject等表格保持连接。

然后,这只是建立一个长条件阵列的问题。在Cake中,您可以指定“OR”条件,如下所示:

array('OR' => array(
    array('Post.title LIKE' => '%one%'),
    array('Post.title LIKE' => '%two%')
))

查看complex find conditions上的doco。您的条件数组看起来像:

array('OR' => array(
    array('KmFile.file_name LIKE' => '%term1%'),
    array('KmFile.file_name LIKE' => '%term2%'),
    array('KmDiscipline.disciplines LIKE' => '%term1%'),
    array('KmDiscipline.disciplines LIKE' => '%term2%'),
    array('KmProject.projects LIKE' => '%term1%'),
    array('KmProject.projects LIKE' => '%term2%'),
    // and so on...
))

显然你想使用循环来构建条件数组。

然后在你的KmFile模型上进行一次查找,加入所有相关模型,并附上您的大项条件。这将返回一个匹配列表,不应该花太长时间。

可能有可能在同一个查询中计算某种相关性得分,但我不知道如何。在任何情况下,一旦你在一个查询中得到你的查找结果,在PHP代码中循环它们并计算每个查询的相关性不应该花太长时间。