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); }
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); }