Example #1
0
 /**
  * @param RequestInterface $request
  * @return \Magento\Framework\DB\Ddl\Table
  * @throws \Exception
  */
 public function buildQuery(RequestInterface $request)
 {
     $searchIndex = $this->indexFactory->create()->load($request->getIndex());
     $weights = [];
     foreach ($searchIndex->getIndexInstance()->getAttributeWeights() as $attr => $weight) {
         $weights[$attr] = pow(2, $weight);
     }
     $indexName = $this->scopeResolver->resolve($request->getIndex(), $request->getDimensions());
     $sphinxQuery = $this->engine->getQuery()->select(['id', new QLExpression('weight()')])->from($indexName)->limit(0, 1000000)->option('max_matches', 1000000)->option('field_weights', $weights)->option('ranker', new QLExpression("expr('sum(word_count*user_weight) + bm25')"));
     //@todo http://habrahabr.ru/company/sphinx/blog/133790/
     $queryContainer = $this->queryContainerFactory->create(['request' => $request]);
     $sphinxQuery = $this->processQuery($request->getQuery(), $sphinxQuery, BoolQuery::QUERY_CONDITION_MUST, $queryContainer);
     $sphinxQuery = $this->addDerivedQueries($queryContainer, $sphinxQuery);
     $result = $sphinxQuery->execute();
     if (isset($_GET) && isset($_GET['debug'])) {
         echo $sphinxQuery->getCompiled();
         echo '<pre>' . print_r($result, true) . '</pre>';
     }
     $documents = [];
     foreach ($result as $item) {
         $document = $this->documentFactory->create([]);
         $document->setId($item['id'])->setCustomAttribute('entity_id', $item['id'])->setCustomAttribute('score', new DataObject(['value' => $item['weight()']]));
         $documents[] = $document;
     }
     $table = $this->temporaryStorage->storeApiDocuments($documents);
     return $table;
 }
 /**
  * Build index query
  *
  * @param RequestInterface $request
  * @return Select
  */
 public function build(RequestInterface $request)
 {
     $select = $this->getSelect()->from(['search_index' => $this->resource->getTableName($request->getIndex())], ['entity_id' => 'search_index.product_id'])->joinLeft(['category_index' => $this->resource->getTableName('catalog_category_product_index')], 'search_index.product_id = category_index.product_id' . ' AND search_index.store_id = category_index.store_id', []);
     $isShowOutOfStock = $this->config->isSetFlag('cataloginventory/options/show_out_of_stock', ScopeInterface::SCOPE_STORE);
     if ($isShowOutOfStock === false) {
         $select->joinLeft(['stock_index' => $this->resource->getTableName('cataloginventory_stock_status')], 'search_index.product_id = stock_index.product_id' . $this->getReadConnection()->quoteInto(' AND stock_index.website_id = ?', $this->storeManager->getWebsite()->getId()), [])->where('stock_index.stock_status = ?', 1);
     }
     return $select;
 }
Example #3
0
 /**
  * @param RequestInterface $request
  * @param Table $documentsTable
  * @return array
  */
 private function processAggregations(RequestInterface $request, Table $documentsTable)
 {
     $aggregations = [];
     $buckets = $request->getAggregation();
     $dataProvider = $this->dataProviderContainer->get($request->getIndex());
     foreach ($buckets as $bucket) {
         $aggregationBuilder = $this->aggregationContainer->get($bucket->getType());
         $aggregations[$bucket->getName()] = $aggregationBuilder->build($dataProvider, $request->getDimensions(), $bucket, $documentsTable);
     }
     return $aggregations;
 }
 /**
  * Build index query
  *
  * @param RequestInterface $request
  * @return Select
  */
 public function build(RequestInterface $request)
 {
     $searchIndexTable = $this->scopeResolver->resolve($request->getIndex(), $request->getDimensions());
     $select = $this->resource->getConnection()->select()->from(['search_index' => $searchIndexTable], ['entity_id' => 'entity_id'])->joinLeft(['cea' => $this->resource->getTableName('catalog_eav_attribute')], 'search_index.attribute_id = cea.attribute_id', []);
     $select = $this->tableMapper->addTables($select, $request);
     $select = $this->processDimensions($request, $select);
     $isShowOutOfStock = $this->config->isSetFlag('cataloginventory/options/show_out_of_stock', ScopeInterface::SCOPE_STORE);
     if ($isShowOutOfStock === false) {
         $select->joinLeft(['stock_index' => $this->resource->getTableName('cataloginventory_stock_status')], 'search_index.entity_id = stock_index.product_id' . $this->resource->getConnection()->quoteInto(' AND stock_index.website_id = ?', $this->storeManager->getWebsite()->getId()), []);
         $select->where('stock_index.stock_status = ?', 1);
     }
     return $select;
 }
Example #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');
     }
     $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;
 }
Example #6
0
 /**
  * Execute the search request with ES.
  *
  * @param RequestInterface $request Search request.
  *
  * @return array
  */
 private function doSearch(RequestInterface $request)
 {
     $searchRequest = ['index' => $request->getIndex(), 'type' => $request->getType(), 'body' => $this->requestMapper->buildSearchRequest($request)];
     return $this->client->search($searchRequest);
 }
 /**
  * {@inheritdoc}
  */
 public function resolve(RequestInterface $request, array $documentIds)
 {
     $aggregations = isset($this->resolvers[$request->getIndex()]) ? $this->resolvers[$request->getIndex()]->resolve($request, $documentIds) : $request->getAggregation();
     return $aggregations;
 }
Example #8
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
        );

        $filtersCount = $queryContainer->getFiltersCount();
        if ($filtersCount > 1) {
            $select->group('entity_id');
            $select->having('COUNT(DISTINCT search_index.attribute_id) = ' . $filtersCount);
        }

        $select = $this->addMatchQueries(
            $request,
            $queryContainer->getDerivedQueries(),
            $scoreBuilder,
            $select,
            $indexBuilder
        );

        $select->limit($request->getSize());
        $select->order('relevance ' . Select::SQL_DESC);
        return $select;
    }
Example #9
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;
    }
Example #10
0
 /**
  * Build adapter dependent query
  *
  * @param RequestInterface $request
  * @throws \LogicException
  * @return Select
  */
 public function buildQuery(RequestInterface $request)
 {
     if (!array_key_exists($request->getIndex(), $this->indexProviders)) {
         throw new \LogicException('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->addDerivedQueries($request, $queryContainer, $scoreBuilder, $select, $indexBuilder);
     $select->limit($request->getSize());
     $select->order('relevance ' . Select::SQL_DESC);
     return $select;
 }
Example #11
0
 /**
  * {@inheritdoc}
  */
 public function build(RequestInterface $request)
 {
     $searchIndexTable = $this->scopeResolver->resolve($request->getIndex(), $request->getDimensions());
     $select = $this->getSelect()->from(['search_index' => $searchIndexTable], ['entity_id' => 'entity_id'])->joinLeft(['tmp' => new \Zend_Db_Expr('(SELECT 1 as search_weight)')], '1=1', '');
     return $select;
 }