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