/** * Build adapter dependent query * * @param RequestInterface $request * @throws \Exception * @return Select */ public function buildQuery(RequestInterface $request) { if (!isset($this->indexProviders[$request->getIndex()])) { throw new \Exception('Index provider not configured'); } $select = $this->indexProviders[$request->getIndex()]->build($request); /** @var ScoreBuilder $scoreBuilder */ $scoreBuilder = $this->scoreBuilderFactory->create(); $select = $this->processQuery($scoreBuilder, $request->getQuery(), $select, BoolQuery::QUERY_CONDITION_MUST); $select = $this->processDimensions($request, $select); $select->columns($scoreBuilder->build()); $select->order($scoreBuilder->getScoreAlias() . ' ' . Select::SQL_DESC); return $select; }
/** * @param RequestInterface $request * @param MatchContainer[] $matchQueries * @param ScoreBuilder $scoreBuilder * @param Select $select * @param IndexBuilderInterface $indexBuilder * @return Select * @internal param QueryContainer $queryContainer */ private function addMatchQueries(RequestInterface $request, array $matchQueries, ScoreBuilder $scoreBuilder, Select $select, IndexBuilderInterface $indexBuilder) { if (!$matchQueries) { $select->columns($scoreBuilder->build()); $select = $this->createAroundSelect($select, $scoreBuilder); } elseif (count($matchQueries) === 1) { $matchContainer = reset($matchQueries); $this->matchBuilder->build($scoreBuilder, $select, $matchContainer->getRequest(), $matchContainer->getConditionType()); $select->columns($scoreBuilder->build()); $select = $this->createAroundSelect($select, $scoreBuilder); } elseif (count($matchQueries) > 1) { $select->columns($scoreBuilder->build()); $select = $this->createAroundSelect($select, $scoreBuilder); $subSelect = $select; $select = $this->resource->getConnection(Resource::DEFAULT_READ_RESOURCE)->select(); $tables = array_merge(array_keys($matchQueries), ['main_select.relevance']); $relevance = implode('.relevance + ', $tables); $select->from(['main_select' => $subSelect], [$this->entityMetadata->getEntityId() => 'entity_id', 'relevance' => sprintf('(%s)', $relevance)]); foreach ($matchQueries as $matchName => $matchContainer) { $matchSelect = $indexBuilder->build($request); $matchScoreBuilder = $this->scoreBuilderFactory->create(); $matchSelect = $this->matchBuilder->build($matchScoreBuilder, $matchSelect, $matchContainer->getRequest(), $matchContainer->getConditionType()); $matchSelect->columns($matchScoreBuilder->build()); $select->join([$matchName => $this->createAroundSelect($matchSelect, $scoreBuilder)], $matchName . '.entity_id = main_select.entity_id', []); } } return $select; }
/** * Build adapter dependent query * * @param RequestInterface $request * @return Select */ public function buildQuery(RequestInterface $request) { /** @var ScoreBuilder $scoreBuilder */ $scoreBuilder = $this->scoreBuilderFactory->create(); $select = $this->processQuery($scoreBuilder, $request->getQuery(), $this->getSelect(), self::BOOL_MUST); $select = $this->processDimensions($request, $select); $tableName = $this->resource->getTableName($request->getIndex()); $select->from($tableName)->columns($scoreBuilder->build())->order($scoreBuilder->getScoreAlias() . ' ' . Select::SQL_DESC); return $select; }
/** * @param RequestInterface $request * @param Select $select * @param IndexBuilderInterface $indexBuilder * @param MatchContainer[] $matchQueries * @return Select */ private function addMatchQueries(RequestInterface $request, Select $select, IndexBuilderInterface $indexBuilder, array $matchQueries) { $queriesCount = count($matchQueries); if ($queriesCount) { $table = $this->temporaryStorage->storeDocumentsFromSelect($select); foreach ($matchQueries as $matchContainer) { $queriesCount--; $matchScoreBuilder = $this->scoreBuilderFactory->create(); $matchSelect = $this->matchBuilder->build($matchScoreBuilder, $indexBuilder->build($request), $matchContainer->getRequest(), $matchContainer->getConditionType()); $select = $this->joinPreviousResultToSelect($matchSelect, $table, $matchScoreBuilder); if ($queriesCount) { $previousResultTable = $table; $table = $this->temporaryStorage->storeDocumentsFromSelect($select); $this->getConnection()->dropTable($previousResultTable->getName()); } } } return $select; }
/** * Build adapter dependent query * * @param RequestInterface $request * @throws \Exception * @return Select */ public function buildQuery(RequestInterface $request) { if (!isset($this->indexProviders[$request->getIndex()])) { throw new \Exception('Index provider not configured'); } $indexBuilder = $this->indexProviders[$request->getIndex()]; $queryContainer = $this->queryContainerFactory->create( [ 'indexBuilder' => $indexBuilder, 'request' => $request ] ); $select = $indexBuilder->build($request); /** @var ScoreBuilder $scoreBuilder */ $scoreBuilder = $this->scoreBuilderFactory->create(); $select = $this->processQuery( $scoreBuilder, $request->getQuery(), $select, BoolQuery::QUERY_CONDITION_MUST, $queryContainer ); $select = $this->processDimensions($request, $select); $select->columns($scoreBuilder->build()); $select->limit(self::SQL_ENTITIES_LIMIT); $filtersCount = $queryContainer->getFiltersCount(); if ($filtersCount > 1) { $select->group('entity_id'); $select->having('COUNT(DISTINCT search_index.attribute_id) = ' . $filtersCount); } $select = $this->createAroundSelect($select, $scoreBuilder); $select->limit($request->getSize()); $matchQueries = $queryContainer->getDerivedQueries(); if ($matchQueries) { $subSelect = $select; $select = $this->resource->getConnection(Resource::DEFAULT_READ_RESOURCE)->select(); $tables = array_merge($queryContainer->getDerivedQueryNames(), ['main_select.relevance']); $relevance = implode('.relevance + ', $tables); $select ->from( ['main_select' => $subSelect], [ $this->entityMetadata->getEntityId() => 'entity_id', 'relevance' => sprintf('(%s)', $relevance), ] ); foreach ($matchQueries as $matchName => $matchSelect) { $select->join( [$matchName => $this->createAroundSelect($matchSelect, $scoreBuilder)], $matchName . '.entity_id = main_select.entity_id', [] ); } } $select->order('relevance ' . Select::SQL_DESC); return $select; }