2011-03-14 121 views
0

如何改進查詢,如下所示?如何提高Zend_Search_Lucene查詢的性能?

我的索引已完全優化,除了item_id是關鍵字字段外,所有字段均未存儲。

問題出在「if($ auth){」部分。如果刪除此部分,搜索時間總是在1秒以內,但是當搜索時間添加此部分時,時間爲5秒或更長。顯然這是一個更復雜的查詢,但我不能沒有它。我需要該部分的邏輯來獲取用戶有權查看的搜索結果。我知道搜索工作本身就是放緩,因爲如果我刪除了「if($ authQuery){$ query-> addSubquery($ authQuery,true);}」這一行,搜索速度相當快。

我想在基本上實現以下邏輯:「如果($ AUTH){」部分:

Lucene的領域gi_aro,gc_aro,i_access和c_access都包括什麼比一個整數每個

更多
if ((array_in({gi_aro}, $gmid) OR {i_access} <= $gid) 
    AND (array_in({gc_aro}, $gmid) {OR c_access} <= $gid)) { 
    include in search results 
} 

{} = Lucene的領域

// keywords query 
$keywords = explode(' ', $keyword); 

$keywordQuery = new Zend_Search_Lucene_Search_Query_Multiterm(); 
foreach ($keywords as $term) { 
    $keywordQuery->addTerm(new Zend_Search_Lucene_Index_Term($term, 'content')); 
    $keywordQuery->addTerm(new Zend_Search_Lucene_Index_Term($term, 'search_display_name')); 
} 

// topcat query 
if (!empty($topcat)) { 
    $term = new Zend_Search_Lucene_Index_Term($topcat, 'topcats'); 
    $topcatQuery = new Zend_Search_Lucene_Search_Query_Term($term); 
} 

// cat query 
if (!empty($cat)) { 
    $term = new Zend_Search_Lucene_Index_Term($cat, 'cats'); 
    $catQuery = new Zend_Search_Lucene_Search_Query_Term($term); 
} 

// only authorized items query 
if ($auth) { 
    $user = JFactory::getUser(); 
    $gid = (int)$user->get('aid'); 
    $gmid = explode(',', $user->gmid); 

    // flexicontent cat auth 
    $gcQuery = new Zend_Search_Lucene_Search_Query_MultiTerm(); 
    foreach ($gmid as $g) { 
    $gcQuery->addTerm(new Zend_Search_Lucene_Index_Term($g, 'gc_aro')); 
    } 

    // stock joomla cat auth 
    $lowCAccessTerm = new Zend_Search_Lucene_Index_Term(0, 'c_access'); 
    $highCAccessTerm = new Zend_Search_Lucene_Index_Term($gid, 'c_access'); 
    $cAccessQuery = new Zend_Search_Lucene_Search_Query_Range($lowCAccessTerm, $highCAccessTerm, true); 

    // ORed flexicontent cat auth & stock joomla cat auth 
    $catAuthQuery = new Zend_Search_Lucene_Search_Query_Boolean(); 
    $catAuthQuery->addSubquery($gcQuery); 
    $catAuthQuery->addSubquery($cAccessQuery); 

    // flexicontent itm auth 
    $giQuery = new Zend_Search_Lucene_Search_Query_MultiTerm(); 
    foreach ($gmid as $g) { 
    $giQuery->addTerm(new Zend_Search_Lucene_Index_Term($g, 'gi_aro')); 
    } 

    // stock joomla itm auth 
    $lowIAccessTerm = new Zend_Search_Lucene_Index_Term(0, 'i_access'); 
    $highIAccessTerm = new Zend_Search_Lucene_Index_Term($gid, 'i_access'); 
    $iAccessQuery = new Zend_Search_Lucene_Search_Query_Range($lowIAccessTerm, $highIAccessTerm, true); 

    // ORed flexicontent itm auth & stock joomla itm auth 
    $itmAuthQuery = new Zend_Search_Lucene_Search_Query_Boolean(); 
    $itmAuthQuery->addSubquery($giQuery); 
    $itmAuthQuery->addSubquery($iAccessQuery); 

    // ANDed itmAuthQuery & catAuthQuery 
    $authQuery = new Zend_Search_Lucene_Search_Query_Boolean(); 
    $authQuery->addSubquery($catAuthQuery, true); 
    $authQuery->addSubquery($itmAuthQuery, true); 
} 

// composite query 
$query = new Zend_Search_Lucene_Search_Query_Boolean(); 
$query->addSubquery($keywordQuery, true); 
// if cat query is set we don't need topcat to restrict result set 
if ($catQuery) { 
    $query->addSubquery($catQuery, true); 
} elseif ($topcatQuery) { 
    $query->addSubquery($topcatQuery, true); 
} 
if ($authQuery) { $query->addSubquery($authQuery, true); } 

// search 
$execTime = new JProfiler(); 
$this->hits = $index->find($query); 
echo $execTime->mark('executed'); 

回答

0

約僅檢查結果而不是索引裏面有什麼?將某種鍵保存到索引(db主鍵,guid,幾乎任何東西)。然後獲取結果並刪除用戶不允許看到的結果。

$allowedArray = $acl->getAllowedIds(); 
// check happens when echoing the content to prevent double cycling (filtering and echoing in view) 
foreach ($result as $item) { 
    if (in_array($item->keyVaue, $allowedArray)) { 
     //echo 
    } 
} 

編輯:注意這取決於大多數查詢的結果。如果在定期查詢中有說的< 50,那麼在PHP中執行就可以了。但是,如果常見的查詢返回10,000結果,它可能不是一個好主意;)

+0

感謝一堆響應,但查詢通常返回超過1000個結果,循環它們都只需要太多的時間。我之前是這麼做的,但後來我意識到循環太昂貴了,所以我開始減少結果集,只「觸摸」我要顯示的結果,但搜索速度太慢。我不記得怎麼回事,但是我暫時把它運行得可以接受。如果速度太慢,我想我必須切換到Solr。 – rushinge 2011-04-01 04:14:10

+0

其他選項將回退到SQL :) – 2011-04-01 10:24:13