예제 #1
0
 /**
  * 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;
 }
예제 #2
0
 /**
  * @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;
 }
예제 #3
0
 /**
  * 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;
 }
예제 #4
0
 /**
  * @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;
 }
예제 #5
0
    /**
     * 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;
    }