public function applyFilters()
 {
     if (KalturaLog::getEnableTests()) {
         KalturaLog::debug('kaltura_entry_criteria ' . serialize($this));
     }
     $this->criteriasLeft = 0;
     KalturaLog::debug("Applies " . count($this->filters) . " filters");
     foreach ($this->filters as $index => $filter) {
         KalturaLog::debug("Applies filter {$index}");
         $this->applyFilter(clone $filter);
     }
     // attach all default criteria from peer
     $this->getDefaultCriteriaFilter()->applyFilter($this);
     if (!$this->hasAdvancedSearchFilter && !count($this->matchClause) && $this->shouldSkipSphinx()) {
         KalturaLog::debug('Skip Sphinx');
         $this->sphinxSkiped = true;
         return;
     }
     $criterionsMap = $this->getMap();
     uksort($criterionsMap, array('SphinxCriteria', 'sortFieldsByPriority'));
     // go over all criterions and try to move them to the sphinx
     foreach ($criterionsMap as $field => $criterion) {
         if (!$criterion instanceof SphinxCriterion) {
             KalturaLog::debug("Criterion [" . $criterion->getColumn() . "] is not sphinx criteria");
             $this->criteriasLeft++;
             continue;
         }
         if ($criterion->apply($this)) {
             KalturaLog::debug("Criterion [" . $criterion->getColumn() . "] attached");
             $this->keyToRemove[] = $field;
         } else {
             KalturaLog::debug("Criterion [" . $criterion->getColumn() . "] failed");
             $this->criteriasLeft++;
         }
     }
     KalturaLog::debug("Applied " . count($this->matchClause) . " matches, " . count($this->whereClause) . " clauses, " . count($this->keyToRemove) . " keys removed, {$this->criteriasLeft} keys left");
     if (count($this->matchClause)) {
         $this->matchClause = array_unique($this->matchClause);
         $matches = reset($this->matchClause);
         if (count($this->matchClause) > 1) {
             $matches = '( ' . implode(' ) ( ', $this->matchClause) . ' )';
         }
         $this->addWhere("MATCH('{$matches}')");
     }
     $conditions = '';
     $i = 0;
     foreach ($this->conditionClause as $conditionClause) {
         if ($this->conditionClause[$i] == '') {
             continue;
         }
         $conditions .= ', (' . $this->conditionClause[$i] . ') as cnd' . $i . ' ';
         $this->addWhere('cnd' . $i . ' > 0');
         $i++;
     }
     $wheres = '';
     KalturaLog::debug("Where clause: " . print_r($this->whereClause, true));
     $this->whereClause = array_unique($this->whereClause);
     if (count($this->whereClause)) {
         $wheres = 'WHERE ' . implode(' AND ', $this->whereClause);
     }
     $orderBy = '';
     $orderByColumns = $this->getOrderByColumns();
     $orderByColumns = array_unique($orderByColumns);
     $setLimit = true;
     $orders = array();
     if (count($orderByColumns)) {
         $replace = $this->getSphinxOrderFields();
         $search = array_keys($replace);
         $this->clearOrderByColumns();
         foreach ($orderByColumns as $orderByColumn) {
             $arr = explode(' ', $orderByColumn);
             $orderField = $arr[0];
             if (isset($replace[$orderField])) {
                 KalturaLog::debug("Add sort field[{$orderField}] copy from [{$orderByColumn}]");
                 $orders[] = str_replace($search, $replace, $orderByColumn);
             } else {
                 KalturaLog::debug("Skip sort field[{$orderField}] from [{$orderByColumn}] limit won't be used in sphinx query");
                 $setLimit = false;
                 $matches = null;
                 if (preg_match('/^\\s*([^\\s]+)\\s+(ASC|DESC)\\s*$/i', $orderByColumn, $matches)) {
                     list($match, $column, $direction) = $matches;
                     if (strtoupper($direction) == Criteria::DESC) {
                         $this->addDescendingOrderByColumn($column);
                     } else {
                         $this->addAscendingOrderByColumn($column);
                     }
                 }
             }
         }
     }
     foreach ($this->orderByClause as $orderByClause) {
         $orders[] = $orderByClause;
     }
     if (count($orders)) {
         $this->applySortRequired = true;
         $orders = array_unique($orders);
         $orderBy = 'ORDER BY ' . implode(',', $orders);
     } else {
         $this->applySortRequired = false;
     }
     $this->ranker = self::RANKER_NONE;
     if (strpos($orderBy, '@weight') !== false) {
         $this->ranker = self::RANKER_SPH04;
     }
     $index = $this->getSphinxIndexName();
     $maxMatches = self::getMaxRecords();
     $limit = $maxMatches;
     if ($this->criteriasLeft) {
         $setLimit = false;
     }
     if ($setLimit && $this->getLimit()) {
         $maxMatches += $this->getOffset();
         $limit = $this->getLimit();
         if ($this->getOffset()) {
             $limit = $this->getOffset() . ", {$limit}";
         }
     }
     $this->executeSphinx($index, $wheres, $orderBy, $limit, $maxMatches, $setLimit, $conditions);
 }
Пример #2
0
 public function applyFilters()
 {
     $objectClass = $this->getIndexObjectName();
     if (KalturaLog::getEnableTests()) {
         KalturaLog::debug('kaltura_entry_criteria ' . serialize($this));
     }
     $this->criteriasLeft = 0;
     KalturaLog::debug("Applies " . count($this->filters) . " filters");
     foreach ($this->filters as $index => $filter) {
         KalturaLog::debug("Applies filter {$index}");
         $this->applyFilter(clone $filter);
     }
     // attach all default criteria from peer
     $objectClass::getDefaultCriteriaFilter()->applyFilter($this);
     if (!$this->hasAdvancedSearchFilter && !count($this->matchClause) && $this->shouldSkipSphinx() && !isset($this->groupByColumn) && !isset($this->selectColumn)) {
         KalturaLog::debug('Skip Sphinx');
         $this->sphinxSkipped = true;
         return;
     }
     $fieldsToKeep = $objectClass::getSphinxConditionsToKeep();
     $criterionsMap = $this->getMap();
     uksort($criterionsMap, array('SphinxCriteria', 'sortFieldsByPriority'));
     // go over all criterions and try to move them to the sphinx
     foreach ($criterionsMap as $field => $criterion) {
         if (!$criterion instanceof SphinxCriterion) {
             KalturaLog::debug("Criterion [" . $criterion->getColumn() . "] is not sphinx criteria");
             $this->criteriasLeft++;
             continue;
         }
         if ($criterion->apply($this)) {
             KalturaLog::debug("Criterion [" . $criterion->getColumn() . "] attached");
             if (!in_array($field, $fieldsToKeep)) {
                 $this->keyToRemove[] = $field;
             }
         } else {
             KalturaLog::debug("Criterion [" . $criterion->getColumn() . "] failed");
             $this->criteriasLeft++;
         }
     }
     KalturaLog::debug("Applied " . count($this->matchClause) . " matches, " . count($this->whereClause) . " clauses, " . count($this->keyToRemove) . " keys removed, {$this->criteriasLeft} keys left");
     // Adds special sphinx optimizations matches
     $this->addSphinxOptimizationMatches($criterionsMap);
     if (count($this->matchClause)) {
         $this->matchClause = array_unique($this->matchClause);
         $matches = reset($this->matchClause);
         if (count($this->matchClause) > 1) {
             $matches = '( ' . implode(' ) ( ', $this->matchClause) . ' )';
         }
         $this->addWhere("MATCH('{$matches}')");
     }
     $conditions = '';
     $i = 0;
     foreach ($this->conditionClause as $conditionClause) {
         if ($this->conditionClause[$i] == '') {
             continue;
         }
         $conditions .= ', (' . $this->conditionClause[$i] . ') as cnd' . $i . ' ';
         $this->addWhere('cnd' . $i . ' > 0');
         $i++;
     }
     $wheres = '';
     KalturaLog::debug("Where clause: " . print_r($this->whereClause, true));
     $this->whereClause = array_unique($this->whereClause);
     if (count($this->whereClause)) {
         $wheres = 'WHERE ' . implode(' AND ', $this->whereClause);
     }
     $orderBy = '';
     $orderByColumns = $this->getOrderByColumns();
     $orderByColumns = array_unique($orderByColumns);
     $usesWeight = false;
     $setLimit = true;
     $orders = array();
     if (count($orderByColumns)) {
         $replace = $objectClass::getIndexOrderList();
         $search = array_keys($replace);
         $this->clearOrderByColumns();
         foreach ($orderByColumns as $orderByColumn) {
             $arr = explode(' ', $orderByColumn);
             $orderField = $arr[0];
             $orderFieldParts = explode(".", $orderField);
             $isWeight = end($orderFieldParts) == "WEIGHT";
             if (isset($replace[$orderField]) || $isWeight) {
                 if ($isWeight) {
                     $replace[$orderField] = "w";
                     $conditions .= ",weight() as w";
                     $usesWeight = true;
                     $search = array_keys($replace);
                 }
                 KalturaLog::debug("Add sort field[{$orderField}] copy from [{$orderByColumn}]");
                 $orders[] = str_replace($search, $replace, $orderByColumn);
             } else {
                 KalturaLog::debug("Skip sort field[{$orderField}] from [{$orderByColumn}] limit won't be used in sphinx query");
                 $setLimit = false;
                 $matches = null;
                 if (preg_match('/^\\s*([^\\s]+)\\s+(ASC|DESC)\\s*$/i', $orderByColumn, $matches)) {
                     list($match, $column, $direction) = $matches;
                     if (strtoupper($direction) == Criteria::DESC) {
                         $this->addDescendingOrderByColumn($column);
                     } else {
                         $this->addAscendingOrderByColumn($column);
                     }
                 }
             }
         }
     }
     foreach ($this->orderByClause as $orderByClause) {
         $orders[] = $orderByClause;
     }
     if (count($orders)) {
         $this->applySortRequired = true;
         $orders = array_unique($orders);
         $orderBy = 'ORDER BY ' . implode(',', $orders);
         if (count($this->numericalOrderConditions)) {
             $conditions .= "," . implode(",", $this->numericalOrderConditions);
         }
     } else {
         $this->applySortRequired = false;
     }
     $this->ranker = self::RANKER_NONE;
     if ($usesWeight) {
         $this->ranker = self::RANKER_BM25;
     }
     $index = kSphinxSearchManager::getSphinxIndexName($objectClass::getObjectIndexName());
     $maxMatches = self::getMaxRecords();
     $limit = $maxMatches;
     if ($this->criteriasLeft) {
         $setLimit = false;
     }
     if ($setLimit && $this->getLimit()) {
         if ($this->getOffset() >= self::MAX_MATCHES) {
             throw new kCoreException("sphinx max matches limit was reached", kCoreException::SPHINX_CRITERIA_EXCEEDED_MAX_MATCHES_ALLOWED);
         }
         $maxMatches = min($maxMatches, $this->getLimit());
         $maxMatches += $this->getOffset();
         $maxMatches = min($maxMatches, self::MAX_MATCHES);
         $limit = $this->getLimit();
         if ($this->getOffset()) {
             $limit = $this->getOffset() . ", {$limit}";
         }
     }
     $this->executeSphinx($index, $wheres, $orderBy, $limit, $maxMatches, $setLimit, $conditions);
 }