2011-03-14 173 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