如何提高Zend_Search_Lucene查询的性能?

时间:2011-03-14 21:04:27

标签: zend-framework search lucene zend-search-lucene

如何改进查询,如下所示?

我的索引已完全优化,除了item_id(关键字字段)外,所有字段均未存储。

问题出在“if($ auth){”部分。如果删除此部分,则搜索时间始终低于1秒,但在搜索时间中添加此部分的时间为5秒或更长。显然这是一个更复杂的查询,但我不能没有它。我需要该部分中的逻辑来仅获取用户有权查看的搜索结果。我知道减速是在搜索工作本身,因为如果我删除行“if($ authQuery){$ query-> addSubquery($ authQuery,true);}”搜索速度非常快。

我试图在“if($ 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 fields

// 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');

1 个答案:

答案 0 :(得分: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
    }
} 

修改:请注意,这取决于大多数查询的结果。如果在常规查询中有&lt; 50结果,那么在PHP中执行就可以了。但是,如果常见查询返回10,000个结果,那可能不是一个好主意;)