Author: Aurelien FOUCRET (aurelien.foucret@smile.fr)
Exemple #1
0
 /**
  * Create a filtered query with an optional fulltext query part.
  *
  * @param ContainerConfigurationInterface $containerConfiguration Search request container configuration.
  * @param string|null                     $queryText              Fulltext query.
  * @param array                           $filters                Filter part of the query.
  * @param string                          $spellingType           For fulltext query : the type of spellchecked applied.
  *
  * @return QueryInterface
  */
 public function createQuery(ContainerConfigurationInterface $containerConfiguration, $queryText, array $filters, $spellingType)
 {
     $queryParams = [];
     if (!empty($filters)) {
         $queryParams = ['filter' => $this->filterQueryBuilder->create($containerConfiguration, $filters)];
     }
     if ($queryText) {
         $queryParams['query'] = $this->fulltextQueryBuilder->create($containerConfiguration, $queryText, $spellingType);
     }
     return $this->queryFactory->create(QueryInterface::TYPE_FILTER, $queryParams);
 }
 /**
  * Rewrite the query.
  *
  * @SuppressWarnings(PHPMD.UnusedFormalParameter)
  *
  * @param QueryBuilder                    $subject         Original query builder.
  * @param \Closure                        $proceed         Original create func.
  * @param ContainerConfigurationInterface $containerConfig Search request container config.
  * @param string                          $queryText       Current query text.
  * @param string                          $spellingType    Spelling type of the query.
  * @param float                           $boost           Original query boost.
  *
  * @return QueryInterface
  */
 public function aroundCreate(QueryBuilder $subject, \Closure $proceed, ContainerConfigurationInterface $containerConfig, $queryText, $spellingType, $boost = 1)
 {
     $storeId = $containerConfig->getStoreId();
     $requestName = $containerConfig->getName();
     $rewriteCacheKey = $requestName . '|' . $storeId . '|' . md5(json_encode($queryText));
     if (!isset($this->rewritesCache[$rewriteCacheKey])) {
         $query = $proceed($containerConfig, $queryText, $spellingType, $boost);
         $rewrites = [];
         if (!is_array($queryText)) {
             $queryText = [$queryText];
         }
         foreach ($queryText as $currentQueryText) {
             $rewrites = array_merge($rewrites, $this->index->getQueryRewrites($containerConfig, $currentQueryText));
         }
         if (!empty($rewrites)) {
             $synonymQueries = [$query];
             $synonymQueriesSpellcheck = SpellcheckerInterface::SPELLING_TYPE_EXACT;
             foreach ($rewrites as $rewrittenQuery => $weight) {
                 $synonymQueries[] = $proceed($containerConfig, $rewrittenQuery, $synonymQueriesSpellcheck, $weight);
             }
             $query = $this->queryFactory->create(QueryInterface::TYPE_BOOL, ['should' => $synonymQueries]);
         }
         $this->rewritesCache[$rewriteCacheKey] = $query;
     }
     return $this->rewritesCache[$rewriteCacheKey];
 }
 /**
  * Phonentic query part.
  *
  * @param ContainerConfigurationInterface $containerConfig Search request container configuration.
  * @param string                          $queryText       The text query.
  *
  * @return QueryInterface
  */
 private function getPhoneticQuery(ContainerConfigurationInterface $containerConfig, $queryText)
 {
     $relevanceConfig = $containerConfig->getRelevanceConfig();
     $analyzer = FieldInterface::ANALYZER_PHONETIC;
     $defaultSearchField = MappingInterface::DEFAULT_SPELLING_FIELD;
     $fuzzyFieldCallback = [$this, 'isFuzzyFieldCallback'];
     $searchFields = $this->getWeightedFields($containerConfig, $analyzer, $fuzzyFieldCallback, $defaultSearchField);
     $queryParams = ['fields' => $searchFields, 'queryText' => $queryText, 'minimumShouldMatch' => "100%", 'tieBreaker' => $relevanceConfig->getTieBreaker(), 'cutoffFrequency' => $relevanceConfig->getCutoffFrequency()];
     if ($relevanceConfig->getPhoneticConfiguration()->isFuzzinessEnabled()) {
         $queryParams['fuzzinessConfig'] = $relevanceConfig->getPhoneticConfiguration()->getFuzzinessConfiguration();
     }
     return $this->queryFactory->create(QueryInterface::TYPE_MULTIMATCH, $queryParams);
 }
Exemple #4
0
 /**
  * Retrieve a query used to apply category filter rule.
  *
  * @param array $excludedCategories Category excluded from the loading (avoid infinite loop in query building when circular references are present).
  *
  * @return QueryInterface
  */
 private function getCategorySearchQuery($excludedCategories)
 {
     $categoryIds = array_diff(explode(',', $this->getValue()), $excludedCategories);
     $subQueries = [];
     foreach ($categoryIds as $categoryId) {
         $subQueries[] = $this->getRule()->getCategorySearchQuery($categoryId, $excludedCategories);
     }
     $query = $this->queryFactory->create(QueryInterface::TYPE_BOOL, ['should' => $subQueries]);
     if (count($subQueries) === 1) {
         $query = current($subQueries);
     }
     return $query;
 }
Exemple #5
0
 /**
  * Build a search query for the current rule.
  *
  * @return QueryInterface
  */
 public function getSearchQuery()
 {
     $queryParams = [];
     $aggregator = $this->getAggregator();
     $value = (bool) $this->getValue();
     $queryClause = $aggregator === 'all' ? 'must' : 'should';
     foreach ($this->getConditions() as $condition) {
         $subQuery = $condition->getSearchQuery();
         if ($subQuery !== null && $subQuery instanceof QueryInterface) {
             if ($value === false) {
                 $subQuery = $this->queryFactory->create(QueryInterface::TYPE_NOT, ['query' => $subQuery]);
             }
             $queryParams[$queryClause][] = $subQuery;
         }
     }
     $query = $this->queryFactory->create(QueryInterface::TYPE_BOOL, $queryParams);
     return $query;
 }
Exemple #6
0
 /**
  * Build search query by category.
  *
  * @param \Magento\Catalog\Api\Data\CategoryInterface $category           Search category.
  * @param array                                       $excludedCategories Categories that should not be used into search query building.
  *                                                                        Used to avoid infinite recursion while building virtual categories rules.
  *
  * @return \Smile\ElasticsuiteCore\Search\Request\QueryInterface
  */
 public function getCategorySearchQuery($category, $excludedCategories = [])
 {
     if (!is_object($category)) {
         $category = $this->categoryFactory->create()->setStoreId($this->getStoreId())->load($category);
     }
     $queryParams = ['cached' => true];
     if ((bool) $category->getIsVirtualCategory() && $category->getIsActive()) {
         $excludedCategories[] = $category->getId();
         $queryParams['must'][] = $this->getVirtualCategoryQuery($category, $excludedCategories);
         $parentCategory = $this->getVirtualRootCategory($category);
         if ($parentCategory && $parentCategory->getId()) {
             $queryParams['must'][] = $this->getCategorySearchQuery($parentCategory, $excludedCategories);
         }
     } elseif ($category->getId() && $category->getIsActive()) {
         $queryParams['should'][] = $this->getStandardCategoryQuery($category);
         foreach ($this->getChildrenVirtualCategories($category, $excludedCategories) as $childrenCategory) {
             $queryParams['should'][] = $this->getVirtualCategoryQuery($childrenCategory, $excludedCategories);
         }
     }
     return $this->queryFactory->create(QueryInterface::TYPE_BOOL, $queryParams);
 }
 /**
  * Transform the condition into a search request query object.
  *
  * @param FieldInterface $field     Filter field.
  * @param array|string   $condition Filter condition.
  *
  * @return QueryInterface
  */
 private function prepareFieldCondition(FieldInterface $field, $condition)
 {
     $queryType = QueryInterface::TYPE_TERMS;
     $condition = $this->prepareCondition($condition);
     if (count(array_intersect(['gt', 'gte', 'lt', 'lte'], array_keys($condition))) >= 1) {
         $queryType = QueryInterface::TYPE_RANGE;
         $condition = ['bounds' => $condition];
     }
     $condition['field'] = $field->getMappingProperty(FieldInterface::ANALYZER_UNTOUCHED);
     if ($condition['field'] === null) {
         $condition['field'] = $field->getMappingProperty(FieldInterface::ANALYZER_STANDARD);
     }
     if (in_array('queryText', array_keys($condition))) {
         $queryType = QueryInterface::TYPE_MATCH;
         $condition['minimumShouldMatch'] = '100%';
     }
     $query = $this->queryFactory->create($queryType, $condition);
     if ($field->isNested()) {
         $queryParams = ['path' => $field->getNestedPath(), 'query' => $query];
         $query = $this->queryFactory->create(QueryInterface::TYPE_NESTED, $queryParams);
     }
     return $query;
 }
 /**
  * Instantiate query from type and params.
  *
  * @param string $queryType   Query type.
  * @param array  $queryParams Query instantiation params.
  *
  * @return QueryInterface
  */
 private function prepareQuery($queryType, $queryParams)
 {
     return $this->queryFactory->create($queryType, $queryParams);
 }
Exemple #9
0
 /**
  * Create a product id filter query.
  *
  * @param array $ids Id to be filtered.
  *
  * @return QueryInterface
  */
 private function getEntityIdFilterQuery($ids)
 {
     return $this->queryFactory->create(QueryInterface::TYPE_TERMS, ['field' => 'entity_id', 'values' => $ids]);
 }
 /**
  * {@inheritDoc}
  */
 public function getFilter()
 {
     $filterParams = ['field' => self::FILTER_FIELD, 'value' => true];
     $filterQuery = $this->queryFactory->create(QueryInterface::TYPE_NOT, ['query' => $this->queryFactory->create(QueryInterface::TYPE_TERM, $filterParams)]);
     return $filterQuery;
 }