Как я могу улучшить производительность этого запроса Zend_Search_Lucene? - PullRequest
0 голосов
/ 15 марта 2011

Как мне улучшить запрос, как показано ниже?

Мой индекс полностью оптимизирован, и все поля не сохранены, за исключением item_id, который является ключевым словом.

Проблема в "раздел if ($ auth) {".Если этот раздел удален, время поиска всегда меньше 1 секунды, но при добавлении этого раздела время поиска составляет 5 секунд и более.Очевидно, это более сложный запрос, но я не могу жить без него.Мне нужна логика в этом разделе, чтобы получать только результаты поиска, которые пользователь имеет право просматривать.Я знаю, что замедление связано с поиском, потому что, если я уберу строку "if ($ authQuery) {$ query-> addSubquery ($ authQuery, true);}", поиск будет довольно быстрым.

Iя пытаюсь в основном влиять на следующую логику в разделе «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
}

{} = поля люцены

// 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 голосов
/ 31 марта 2011

Как насчет проверки только результатов, не входящих в индекс?Сохраните какой-нибудь ключ в индексе (первичный ключ БД, 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 это нормально.Но если общий запрос возвращает около 10000 результатов, это может быть не очень хорошей идеей;) </p>

...