2013-08-28 103 views
0

我有一個包含文件列表(大約6000個文件)的數據庫。所有這些文件都有一些額外的詳細信息(如項目編號,部門,客戶,評論,學科)。搜索代碼優化 - CakePHP

雖然代碼和搜索起作用,但速度很慢。有兩個條件的簡單搜索大約需要一分鐘才能完成。

我的代碼如下。我想知道的是,我可以做些什麼來簡化和優化我的搜索功能?

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相當陌生,所以不知道該怎麼做來改進它。

任何援助將不勝感激。

回答

0

爲了讓速度更快,您必須儘可能多地推遲數據庫的責任(數據庫現在真的很快!),並儘量減少PHP和數據庫之間的來回。理想情況下,您可以通過單個查詢獲取所有搜索結果(例如,單個呼叫find)。

您會指定joins,這樣您的KmFile模型就會與您的KmClient,KmProject等表格加在一起。

然後,這只是建立一個長條件數組的問題。在complex find conditions

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

退房的DOCO:蛋糕,你可以指定 'OR' 條件是這樣的。你的條件陣列看起來像這樣:

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代碼中循環查找結果並計算每個查詢的相關性應該不會太長。