Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
No results found
Show changes
Commits on Source (8)
Showing
with 136 additions and 611 deletions
......@@ -17,7 +17,7 @@
],
"require": {
"php": ">=8.1",
"ramsey/collection": "^1.2",
"ramsey/collection": "^2",
"elasticsearch/elasticsearch": "^8.5",
"vlucas/phpdotenv": "^5.4.1"
},
......
......@@ -3,23 +3,17 @@
namespace IQDEV\ElasticSearch\Config;
use IQDEV\ElasticSearch\Configuration;
use IQDEV\ElasticSearch\Mapping;
class BaseConfiguration implements Configuration
{
public function __construct(
private readonly Mapping $mapping,
) {
}
public function getIndexName(): string
{
return $_ENV['IQ_ES_PRODUCT_SEARCH_INDEX'];
}
public function getMapping(): Mapping
public function getMapping(): array
{
return $this->mapping;
return include __DIR__.'/product.mappings.php';
}
public function getSettings(): array
......
<?php
declare(strict_types=1);
namespace IQDEV\ElasticSearch\Config\Mapping;
use IQDEV\ElasticSearch\Mapping;
class ProductMapping extends Mapping
{
public function getPropertiesMap(): array
{
return [
'data' => [
'type' => 'object',
'enabled' => false,
],
'full_search_content' => [
'type' => 'text',
],
'suggest_search_content' => [
'type' => 'text',
'analyzer' => 'autocomplete',
'search_analyzer' => 'standard',
],
'category_id' => [
'type' => 'keyword',
'index' => false,
],
'rating' => [
'type' => 'double',
'index' => false,
],
'popular' => [
'type' => 'double',
'index' => false,
],
];
}
}
......@@ -16,7 +16,7 @@ class MappingValidator
*/
public static function isPropertyExists(Configuration $configuration, string $property): bool
{
$properties = array_keys($configuration->getMapping()->es()['properties'] ?? []);
$properties = array_keys($configuration->getMapping()['properties'] ?? []);
return in_array($property, $properties, true);
}
......
......@@ -20,7 +20,11 @@ return [
],
'rating' => [
'type' => 'double',
'index' => false,
'index' => true,
],
'new' => [
'type' => 'boolean',
'index' => true
],
'popular' => [
'type' => 'double',
......
......@@ -6,7 +6,7 @@ interface Configuration
{
public function getIndexName(): string;
public function getMapping(): Mapping;
public function getMapping(): array;
public function getSettings(): array;
}
<?php
namespace IQDEV\ElasticSearch\Converter;
use IQDEV\ElasticSearch\Config\MappingValidator;
use IQDEV\ElasticSearch\Configuration;
use IQDEV\ElasticSearch\Criteria;
use IQDEV\ElasticSearch\Document\Property\PropertyType;
use IQDEV\ElasticSearch\Request\Filter\Collection\FilterCollection;
use IQDEV\ElasticSearch\Request\Filter\Collection\FilterGroupCollection;
use IQDEV\ElasticSearch\Request\Filter\Collection\PostFilterCollection;
use IQDEV\ElasticSearch\Request\Filter\Collection\QueryFilterCollection;
use IQDEV\ElasticSearch\Request\Filter\Filter;
use IQDEV\ElasticSearch\Request\Filter\FilterOperator;
use IQDEV\ElasticSearch\Request\Filter\FilterType;
use IQDEV\ElasticSearch\Request\Filter\LogicOperator;
use IQDEV\ElasticSearch\Request\Filter\Value\FilterKeyword;
use IQDEV\ElasticSearch\Request\Filter\Value\FilterNumber;
use IQDEV\ElasticSearch\Request\Order\Order;
use IQDEV\ElasticSearch\Request\Search\Search;
use IQDEV\ElasticSearch\Request\Search\SearchQuery;
use IQDEV\ElasticSearch\Search\Aggs\Aggs;
use IQDEV\ElasticSearch\Search\Aggs\AggsFacetStats;
use IQDEV\ElasticSearch\Search\Aggs\AggsFacetTerms;
use IQDEV\ElasticSearch\Search\BoolQuery\FilterKeywordFacet;
use IQDEV\ElasticSearch\Search\BoolQuery\FilterNumberFacet;
use IQDEV\ElasticSearch\Search\BoolQuery\Query;
use IQDEV\ElasticSearch\Search\BoolQuery\Stats;
use IQDEV\ElasticSearch\Search\BoolQuery\Terms;
use IQDEV\ElasticSearch\Search\Nested;
use IQDEV\ElasticSearch\Search\Pagination;
use IQDEV\ElasticSearch\Search\Request;
final class CriteriaToEsRequest
{
public function __construct(
private readonly Configuration $configuration,
) {
}
public function fromCriteria(Criteria $criteria): Request
{
$request = new Request();
$request = $this->pagination($request, $criteria);
$request = $this->order($request, $criteria);
$request = $this->search($request, $criteria);
$request = $this->filter($request, $criteria);
$request = $this->aggs($request, $criteria);
return $request;
}
private function pagination(Request $request, Criteria $criteria): Request
{
$request = clone $request;
$request->setPagination(new Pagination($criteria->getPagination()->limit, $criteria->getPagination()->offset));
return $request;
}
private function order(Request $request, Criteria $criteria): Request
{
$request = clone $request;
if (true === $criteria->getSorting()->isEmpty()) {
return $request;
}
foreach ($criteria->getSorting() as $order) {
/** @var Order $order */
$request->getSort()->add($order);
}
return $request;
}
private function search(Request $request, Criteria $criteria): Request
{
$request = clone $request;
foreach ($criteria->getSearch() as $search) {
/** @var Search $search */
$searchQuery = new SearchQuery($search);
if ($search->getProperty()->getType() === PropertyType::TEXT) {
$request->getQueryMatch()->add($searchQuery->toQueryMatch());
} else {
$request->getQuery()->getMust()->add($searchQuery->toMust($this->configuration));
}
}
return $request;
}
private function filter(Request $request, Criteria $criteria): Request
{
$request = clone $request;
if ($criteria->getFilters()->isEmpty()) {
return $request;
}
$queryFilters = $criteria->getFilters()->getFilterCollectionByType(FilterType::QUERY);
$postFilters = $criteria->getFilters()->getFilterCollectionByType(FilterType::POST);
$this->addFilterToRequest($request, $queryFilters);
$this->addPostFilterToRequest($request, $postFilters);
return $request;
}
private function separatePropertyTypes(FilterCollection $filterCollection): array
{
$propertyFilter = new FilterCollection();
$nestedFilter = new FilterCollection();
foreach ($filterCollection as $groupFilter) {
/** @var FilterGroupCollection $groupFilter */
$propertyGroupCollection = new FilterGroupCollection();
$nestedGroupCollection = new FilterGroupCollection();
$propertyGroupCollection->setLogicOperator($groupFilter->getLogicOperator());
$nestedGroupCollection->setLogicOperator($groupFilter->getLogicOperator());
foreach ($groupFilter as $filter) {
/** @var Filter $filter */
if (true === MappingValidator::isPropertyExists($this->configuration, $filter->field()->value())) {
$propertyGroupCollection->add($filter);
} else {
$nestedGroupCollection->add($filter);
}
}
if (false === $propertyGroupCollection->isEmpty()) {
$propertyFilter->add($propertyGroupCollection);
}
if (false === $nestedGroupCollection->isEmpty()) {
$nestedFilter->add($nestedGroupCollection);
}
}
return [$propertyFilter, $nestedFilter];
}
private function addFilterToRequest(Request $request, QueryFilterCollection $filterCollection): void
{
[$propertyFilterCollection, $nestedFilterCollection] = $this->separatePropertyTypes($filterCollection);
$this->addPropertyFilterToRequest($request, $propertyFilterCollection);
$this->addNestedFilterToRequest($request, $nestedFilterCollection);
}
private function addPostFilterToRequest(Request $request, PostFilterCollection $filterCollection): void
{
[$propertyFilterCollection, $nestedFilterCollection] = $this->separatePropertyTypes($filterCollection);
$this->addPropertyPostFilterToRequest($request, $propertyFilterCollection);
$this->addNestedPostFilterToRequest($request, $nestedFilterCollection);
}
private function addPropertyFilterToRequest(Request $request, FilterCollection $filterCollection): void
{
$keywordFilterCollection = $this->getKeywordFilter($filterCollection);
foreach ($keywordFilterCollection->getFilter() as $filter) {
$request->getQuery()->getFilter()->add($filter);
}
foreach ($keywordFilterCollection->getShould() as $should) {
$request->getQuery()->getShould()->add($should);
}
$numberFilterCollection = $this->getNumberFilter($filterCollection);
foreach ($numberFilterCollection->getFilter() as $filter) {
$request->getQuery()->getFilter()->add($filter);
}
foreach ($numberFilterCollection->getShould() as $should) {
$request->getQuery()->getShould()->add($should);
}
}
private function addPropertyPostFilterToRequest(Request $request, FilterCollection $filterCollection): void
{
$keywordFilterCollection = $this->getKeywordFilter($filterCollection);
foreach ($keywordFilterCollection->getFilter() as $filter) {
$request->getPostFilter()->getFilter()->add($filter);
}
foreach ($keywordFilterCollection->getShould() as $should) {
$request->getPostFilter()->getShould()->add($should);
}
$numberFilterCollection = $this->getNumberFilter($filterCollection);
foreach ($numberFilterCollection->getFilter() as $filter) {
$request->getPostFilter()->getFilter()->add($filter);
}
foreach ($numberFilterCollection->getShould() as $should) {
$request->getPostFilter()->getShould()->add($should);
}
}
private function addNestedFilterToRequest(Request $request, FilterCollection $filterCollection): void
{
$keywordFilterCollection = $this->getKeywordFilter($filterCollection);
$keywordFilter = new Nested();
$keywordFilter->setPath('search_data');
if (false === $keywordFilterCollection->isEmpty()) {
$keywordNestedFilterQuery = clone $keywordFilter;
$keywordNestedFilterQuery->setQuery($keywordFilterCollection);
$request->getQuery()->getFilter()->add($keywordNestedFilterQuery);
}
$numberFilterCollection = $this->getNumberFilter($filterCollection);
$numberFilter = new Nested();
$numberFilter->setPath('search_data');
if (false === $numberFilterCollection->isEmpty()) {
$numberNestedFilterQuery = clone $numberFilter;
$numberNestedFilterQuery->setQuery($numberFilterCollection);
$request->getQuery()->getFilter()->add($numberNestedFilterQuery);
}
}
private function addNestedPostFilterToRequest(Request $request, FilterCollection $postFilter): void
{
$keywordFilterCollection = $this->getKeywordFilter($postFilter);
$keywordFilter = new Nested();
$keywordFilter->setPath('search_data');
if (false === $keywordFilterCollection->isEmpty()) {
$keywordNestedFilterQuery = clone $keywordFilter;
$keywordNestedFilterQuery->setQuery($keywordFilterCollection);
$request->getPostFilter()->getFilter()->add($keywordNestedFilterQuery);
}
$numberFilterCollection = $this->getNumberFilter($postFilter);
$numberFilter = new Nested();
$numberFilter->setPath('search_data');
if (false === $numberFilterCollection->isEmpty()) {
$numberNestedFilterQuery = clone $numberFilter;
$numberNestedFilterQuery->setQuery($numberFilterCollection);
$request->getPostFilter()->getFilter()->add($numberNestedFilterQuery);
}
}
private function getNumberFilter(FilterCollection $filterCollection, array $excludeFilter = []): Query
{
$numberFilter = new Query();
if ($filterCollection->isEmpty()) {
return $numberFilter;
}
$ranges = [];
foreach ($filterCollection as $filterGroup) {
/** @var FilterGroupCollection $filterGroup */
if ($filterGroup->isEmpty()) {
continue;
}
$group = $filterGroup->getLogicOperator() === LogicOperator::OR ? count($ranges) + 1 : 0;
if (!isset($ranges[$group])) {
$ranges[$group] = [];
}
foreach ($filterGroup as $filter) {
/** @var Filter $filter */
$value = $filter->value()->value();
$field = $filter->field()->value();
if (in_array($field, $excludeFilter, true)) {
continue;
}
if (in_array($filter->operator(), [FilterOperator::LT, FilterOperator::LTE], true)) {
$ranges[$group][$field][$filter->operator()->value] = $value;
continue;
}
if (in_array($filter->operator(), [FilterOperator::GT, FilterOperator::GTE], true)) {
$ranges[$group][$field][$filter->operator()->value] = $value;
}
}
}
if (false === empty($ranges)) {
foreach ($ranges as $iGroup => $group) {
foreach ($group as $field => $range) {
$isProperty = MappingValidator::isPropertyExists($this->configuration, $field);
$facet = $isProperty ? new Stats($field, $range) : new FilterNumberFacet(
$field,
$range
);
if ($iGroup === 0) {
$numberFilter->getFilter()->add($facet);
} else {
$numberFilter->getShould()->add($facet);
}
}
}
}
return $numberFilter;
}
private function getKeywordFilter(FilterCollection $filterCollection, array $excludeFilter = []): Query
{
$keywordFilter = new Query();
if ($filterCollection->isEmpty()) {
return $keywordFilter;
}
foreach ($filterCollection as $filterGroup) {
/** @var FilterGroupCollection $filterGroup */
if ($filterGroup->isEmpty()) {
continue;
}
$should = $filterGroup->getLogicOperator() === LogicOperator::OR;
foreach ($filterGroup as $filter) {
/** @var Filter $filter */
$value = $filter->value()->value();
$field = $filter->field()->value();
$isProperty = MappingValidator::isPropertyExists($this->configuration, $field);
if (in_array($field, $excludeFilter, true)) {
continue;
}
if (in_array($filter->operator(), [FilterOperator::LT, FilterOperator::LTE], true)) {
continue;
}
if (in_array($filter->operator(), [FilterOperator::GT, FilterOperator::GTE], true)) {
continue;
}
if (is_array($value)) {
$value = array_map(static fn($v) => (string)$v, $value);
} else {
$value = (string)$value;
}
if ($should) {
$keywordFilter->getShould()->add($isProperty ? new Terms($field, $value) : new FilterKeywordFacet($field, $value));
} else {
$keywordFilter->getFilter()->add($isProperty ? new Terms($field, $value) : new FilterKeywordFacet($field, $value));
}
}
}
return $keywordFilter;
}
private function aggs(Request $request, Criteria $criteria): Request
{
$request = clone $request;
if ($criteria->getFilters()->isEmpty() && $criteria->getSearch()->isEmpty()) {
return $request;
}
$request->getAggs()->add(
AggsFacetTerms::create(
'keyword_facet',
'keyword_facet'
)
);
$request->getAggs()->add(
AggsFacetStats::create(
'number_facet',
'number_facet'
)
);
$postFilters = $criteria->getFilters()->getFilterCollectionByType(FilterType::POST);
$getKey = static fn(string $type, string $name): string => sprintf('%s_facet_%s', $type, $name);
foreach ($postFilters as $filterGroup) {
/** @var FilterGroupCollection $filterGroup */
foreach ($filterGroup as $filter) {
/** @var Filter $filter */
$field = $filter->field()->value();
if ($filter->value() instanceof FilterNumber) {
continue;
}
if (in_array($filter->operator(), [], true)) {
continue;
}
if ($filter->value() instanceof FilterKeyword) {
$aggsFiltered = new Aggs($getKey('keyword', $field));
$aggsFiltered->addAggs(
AggsFacetTerms::create(
'agg_special',
'keyword_facet'
)
);
$queryKeywordFiltered = new Query();
$keywordFilter = $this->getKeywordFilter($postFilters, [$field]);
$numberFilter = $this->getNumberFilter($postFilters);
if (false === $keywordFilter->isEmpty()) {
$nestedFilterKeyword = new Nested();
$nestedFilterKeyword->setPath('search_data')
->setQuery($keywordFilter);
$queryKeywordFiltered->getFilter()->add($nestedFilterKeyword);
}
if (false === $numberFilter->isEmpty()) {
$nestedFilterNumber = new Nested();
$nestedFilterNumber->setPath('search_data')
->setQuery($numberFilter);
$queryKeywordFiltered->getFilter()->add($nestedFilterNumber);
}
if ($queryKeywordFiltered->isEmpty() === false) {
$aggsFiltered->setQuery($queryKeywordFiltered);
} else {
$aggsFiltered->setNested((new Nested())->setPath('search_data'));
}
$request->getAggs()->add($aggsFiltered);
}
}
}
$keywordFilter = $this->getKeywordFilter($postFilters);
$numberFilter = $this->getNumberFilter($postFilters);
$aggsKeywordFiltered = new Aggs('keyword_facet_filtered');
$aggsKeywordFiltered->addAggs(
AggsFacetTerms::create(
'all_keyword_facet_filtered',
'keyword_facet'
)
);
$queryKeywordFiltered = new Query();
$aggsNumberFiltered = new Aggs('number_facet_filtered');
$aggsNumberFiltered->addAggs(
AggsFacetStats::create(
'all_number_facet_filtered',
'number_facet'
)
);
$queryNumberFiltered = new Query();
if (false === $keywordFilter->isEmpty()) {
$nestedFilterKeyword = new Nested();
$nestedFilterKeyword->setPath('search_data')
->setQuery($keywordFilter);
$queryKeywordFiltered->getFilter()->add($nestedFilterKeyword);
$queryNumberFiltered->getFilter()->add($nestedFilterKeyword);
}
if (false === $numberFilter->isEmpty()) {
$nestedFilterNumber = new Nested();
$nestedFilterNumber->setPath('search_data')
->setQuery($numberFilter);
$queryKeywordFiltered->getFilter()->add($nestedFilterNumber);
$queryNumberFiltered->getFilter()->add($nestedFilterNumber);
}
if (false === $queryKeywordFiltered->isEmpty()) {
$aggsKeywordFiltered->setQuery($queryKeywordFiltered);
} else {
$aggsKeywordFiltered->setNested((new Nested())->setPath('search_data'));
}
if (false === $queryNumberFiltered->isEmpty()) {
$aggsNumberFiltered->setQuery($queryNumberFiltered);
} else {
$aggsNumberFiltered->setNested((new Nested())->setPath('search_data'));
}
$request->getAggs()
->add($aggsKeywordFiltered)
->add($aggsNumberFiltered);
return $request;
}
}
......@@ -5,10 +5,8 @@ declare(strict_types=1);
namespace IQDEV\ElasticSearch\Converter\Request\Aggregation;
use IQDEV\ElasticSearch\Configuration;
use IQDEV\ElasticSearch\Criteria;
use IQDEV\ElasticSearch\Request\Filter\Collection\FilterGroupCollection;
use IQDEV\ElasticSearch\Request\Filter\Filter;
use IQDEV\ElasticSearch\Request\Filter\FilterType;
use IQDEV\ElasticSearch\Criteria\Criteria;
use IQDEV\ElasticSearch\Criteria\Filter\FilterType;
use IQDEV\ElasticSearch\Search\Aggs\AggsCollection;
use IQDEV\ElasticSearch\Search\Aggs\AggsFacetStats;
use IQDEV\ElasticSearch\Search\Aggs\AggsFacetTerms;
......@@ -25,27 +23,37 @@ class Aggregation
public function convertToQuery(): void
{
$this->aggregations->add(
AggsFacetTerms::create(
'keyword_facet',
'keyword_facet'
)
);
$this->aggregations->add(
AggsFacetStats::create(
'number_facet',
'number_facet'
)
);
$postFilterCollection = $this->criteria->getFilters()->getFilterCollectionByType(FilterType::POST);
$filterAggregation = new FilterAggregation($this->configuration, $postFilterCollection->getKeywordFilters());
$filterAggregation->updateRequestAggregation($this->aggregations);
$fullAggregation = new FullAggregation($this->configuration, $postFilterCollection);
$fullAggregation->updateRequestAggregation($this->aggregations);
$queryFilterCollection = $this->criteria->getFilters()->getFilterCollectionByType(FilterType::QUERY);
if (false === $this->criteria->getSearch()->isEmpty() || false === $this->criteria->getFilters()->isEmpty()) {
$this->aggregations->add(
AggsFacetTerms::create(
'keyword_facet', 'keyword_facet'
)
);
$this->aggregations->add(
AggsFacetStats::create(
'number_facet', 'number_facet'
)
);
$filterAggregation = new FilterAggregation($this->configuration, $queryFilterCollection);
$filterAggregation->updateRequestAggregation($this->aggregations);
$fullAggregation = new FullAggregation($this->configuration, $queryFilterCollection);
$fullAggregation->updateRequestAggregation($this->aggregations);
}
if (false === $this->criteria->getAggs()->isEmpty()) {
$propertyAggregation = new PropertyAggregation(
$this->configuration,
$queryFilterCollection,
$this->criteria->getAggs(),
);
$propertyAggregation->updateRequestAggregation($this->aggregations);
}
}
public function getAggregation(): AggsCollection
......
......@@ -6,14 +6,12 @@ namespace IQDEV\ElasticSearch\Converter\Request\Aggregation;
use IQDEV\ElasticSearch\Configuration;
use IQDEV\ElasticSearch\Converter\Request\FilterQuery;
use IQDEV\ElasticSearch\Request\Filter\Collection\FilterCollection;
use IQDEV\ElasticSearch\Request\Filter\Collection\FilterGroupCollection;
use IQDEV\ElasticSearch\Request\Filter\Filter;
use IQDEV\ElasticSearch\Request\Filter\Value\FilterKeyword;
use IQDEV\ElasticSearch\Criteria\Filter\Collection\FilterCollection;
use IQDEV\ElasticSearch\Criteria\Filter\Collection\FilterGroupCollection;
use IQDEV\ElasticSearch\Criteria\Filter\Filter;
use IQDEV\ElasticSearch\Search\Aggs\Aggs;
use IQDEV\ElasticSearch\Search\Aggs\AggsCollection;
use IQDEV\ElasticSearch\Search\Aggs\AggsFacetTerms;
use IQDEV\ElasticSearch\Search\BoolQuery\Query;
use IQDEV\ElasticSearch\Search\Nested;
class FilterAggregation
......
......@@ -6,20 +6,15 @@ namespace IQDEV\ElasticSearch\Converter\Request\Aggregation;
use IQDEV\ElasticSearch\Configuration;
use IQDEV\ElasticSearch\Converter\Request\FilterQuery;
use IQDEV\ElasticSearch\Request\Filter\Collection\FilterCollection;
use IQDEV\ElasticSearch\Criteria\Filter\Collection\FilterCollection;
use IQDEV\ElasticSearch\Search\Aggs\Aggs;
use IQDEV\ElasticSearch\Search\Aggs\AggsCollection;
use IQDEV\ElasticSearch\Search\Aggs\AggsFacetStats;
use IQDEV\ElasticSearch\Search\Aggs\AggsFacetTerms;
use IQDEV\ElasticSearch\Search\BoolQuery\Query;
use IQDEV\ElasticSearch\Search\Nested;
class FullAggregation
{
private Query $queryKeywordFiltered;
private Query $queryNumberFiltered;
public function __construct(
private readonly Configuration $configuration,
private readonly FilterCollection $filterCollection,
......
<?php
declare(strict_types=1);
namespace IQDEV\ElasticSearch\Converter\Request\Aggregation;
use IQDEV\ElasticSearch\Configuration;
use IQDEV\ElasticSearch\Converter\Request\FilterQuery;
use IQDEV\ElasticSearch\Criteria\Filter\Collection\FilterCollection;
use IQDEV\ElasticSearch\Document\Property\PropertyType;
use IQDEV\ElasticSearch\Search\Aggs\Aggs;
use IQDEV\ElasticSearch\Search\Aggs\AggsCollection;
use IQDEV\ElasticSearch\Search\Aggs\Terms;
class PropertyAggregation
{
public function __construct(
private readonly Configuration $configuration,
private readonly FilterCollection $filterCollection,
private readonly \IQDEV\ElasticSearch\Criteria\Aggs\AggsCollection $aggsCollection,
) {
}
public function updateRequestAggregation(AggsCollection $original): void
{
$queryFilterBuilder = new FilterQuery($this->configuration, $this->filterCollection);
$query = $queryFilterBuilder->getQuery();
/** @var \IQDEV\ElasticSearch\Criteria\Aggs\Aggs $aggs */
foreach ($this->aggsCollection as $aggs) {
$property = $aggs->getProperty();
if ($property->getType() !== PropertyType::BASE) {
continue;
}
$aggs = new Aggs($property->getKey());
if (false === $query->isEmpty()) {
$aggs->setQuery($query);
$aggs->addAggs(
(new Aggs($property->getKey()))
->setTerms(new Terms($property->getKey()))
);
} else {
$aggs->setTerms(new Terms($property->getKey()));
}
$aggs->addAggs(
(new Aggs($property->getKey()))
->setTerms(new Terms($property->getKey()))
);
$original->add($aggs);
}
}
}
......@@ -4,7 +4,7 @@ declare(strict_types=1);
namespace IQDEV\ElasticSearch\Converter\Request\Collection;
use IQDEV\ElasticSearch\Request\Filter\Collection\FilterCollection;
use IQDEV\ElasticSearch\Criteria\Filter\Collection\FilterCollection;
class NestedFilterCollection extends FilterCollection
{
......
......@@ -4,7 +4,7 @@ declare(strict_types=1);
namespace IQDEV\ElasticSearch\Converter\Request\Collection;
use IQDEV\ElasticSearch\Request\Filter\Collection\FilterCollection;
use IQDEV\ElasticSearch\Criteria\Filter\Collection\FilterCollection;
class PropertyFilterCollection extends FilterCollection
{
......
......@@ -6,14 +6,12 @@ namespace IQDEV\ElasticSearch\Converter\Request;
use IQDEV\ElasticSearch\Configuration;
use IQDEV\ElasticSearch\Converter\Request\Aggregation\Aggregation;
use IQDEV\ElasticSearch\Criteria;
use IQDEV\ElasticSearch\Criteria\Criteria;
use IQDEV\ElasticSearch\Criteria\Filter\Collection\PostFilterCollection;
use IQDEV\ElasticSearch\Criteria\Filter\Collection\QueryFilterCollection;
use IQDEV\ElasticSearch\Criteria\Search\Search;
use IQDEV\ElasticSearch\Criteria\Search\SearchQuery;
use IQDEV\ElasticSearch\Document\Property\PropertyType;
use IQDEV\ElasticSearch\Request\Filter\Collection\PostFilterCollection;
use IQDEV\ElasticSearch\Request\Filter\Collection\QueryFilterCollection;
use IQDEV\ElasticSearch\Request\Search\Search;
use IQDEV\ElasticSearch\Request\Search\SearchQuery;
use IQDEV\ElasticSearch\Search\Aggs\AggsFacetStats;
use IQDEV\ElasticSearch\Search\Aggs\AggsFacetTerms;
use IQDEV\ElasticSearch\Search\Pagination;
class CriteriaRequestBuilder extends RequestBuilder
......@@ -42,9 +40,7 @@ class CriteriaRequestBuilder extends RequestBuilder
$this->setFilter();
}
if (false === $this->criteria->getSearch()->isEmpty() || false === $this->criteria->getFilters()->isEmpty()) {
$this->setAggregations();
}
$this->setAggregations();
}
public function setPagination(): void
......
......@@ -2,11 +2,10 @@
declare(strict_types=1);
namespace IQDEV\ElasticSearch\Converter;
namespace IQDEV\ElasticSearch\Converter\Request;
use IQDEV\ElasticSearch\Configuration;
use IQDEV\ElasticSearch\Converter\Request\CriteriaRequestBuilder;
use IQDEV\ElasticSearch\Criteria;
use IQDEV\ElasticSearch\Criteria\Criteria;
use IQDEV\ElasticSearch\Search\Request;
final class CriteriaToRequest
......
......@@ -5,8 +5,8 @@ declare(strict_types=1);
namespace IQDEV\ElasticSearch\Converter\Request\Filter;
use IQDEV\ElasticSearch\Esable;
use IQDEV\ElasticSearch\Request\Filter\Collection\FilterGroupCollection;
use IQDEV\ElasticSearch\Request\Filter\LogicOperator;
use IQDEV\ElasticSearch\Criteria\Filter\Collection\FilterGroupCollection;
use IQDEV\ElasticSearch\Criteria\Filter\LogicOperator;
use IQDEV\ElasticSearch\Search\BoolQuery\Query;
use IQDEV\ElasticSearch\Search\Nested;
......@@ -18,12 +18,12 @@ abstract class AbstractFilterQuery
$this->query = new Query();
}
protected function setFilterByLogic(LogicOperator $logicOperator, Esable $filter): void
protected function setFilterByLogic(Query $query, LogicOperator $logicOperator, Esable $filter): void
{
match ($logicOperator) {
LogicOperator::AND => $this->query->getFilter()->add($filter),
LogicOperator::OR => $this->query->getShould()->add($filter),
LogicOperator::NOT => $this->query->getMustNot()->add($filter),
LogicOperator::AND => $query->getFilter()->add($filter),
LogicOperator::OR => $query->getShould()->add($filter),
LogicOperator::NOT => $query->getMustNot()->add($filter),
};
}
......
......@@ -6,8 +6,8 @@ namespace IQDEV\ElasticSearch\Converter\Request\Filter;
use IQDEV\ElasticSearch\Converter\Request\Filter\Type\KeywordFilterType;
use IQDEV\ElasticSearch\Converter\Request\Filter\Type\RangeFilterType;
use IQDEV\ElasticSearch\Request\Filter\Collection\FilterGroupCollection;
use IQDEV\ElasticSearch\Request\Filter\Filter;
use IQDEV\ElasticSearch\Criteria\Filter\Collection\FilterGroupCollection;
use IQDEV\ElasticSearch\Criteria\Filter\Filter;
use IQDEV\ElasticSearch\Search\BoolQuery\Query;
use IQDEV\ElasticSearch\Search\BoolQuery\Terms;
use IQDEV\ElasticSearch\Search\Nested;
......@@ -19,12 +19,14 @@ class NestedFilter extends AbstractFilterQuery
public function getQuery(FilterGroupCollection $filterGroupCollection, array $exclude): Nested
{
$query = new Query();
$keywordFiltersGroup = $filterGroupCollection->getKeywordFilters($exclude);
foreach ($keywordFiltersGroup as $keywordFilter) {
/** @var Filter $keywordFilter */
$esableFilter = new KeywordFilterType($keywordFilter);
$this->setFilterByLogic($filterGroupCollection->getLogicOperator(), $this->getNested($esableFilter, self::NESTED_KEYWORD_PATH));
$this->setFilterByLogic($query, $filterGroupCollection->getLogicOperator(), $this->getNested($esableFilter, self::NESTED_KEYWORD_PATH));
}
$rangeFilterGroup = $filterGroupCollection->getRangeFilters($exclude);
......@@ -33,12 +35,12 @@ class NestedFilter extends AbstractFilterQuery
/** @var FilterGroupCollection $filterGroup */
$esableFilter = new RangeFilterType($filterGroup);
$this->setFilterByLogic($filterGroupCollection->getLogicOperator(), $this->getNested($esableFilter, self::NESTED_RANGE_PATH));
$this->setFilterByLogic($query, $filterGroupCollection->getLogicOperator(), $this->getNested($esableFilter, self::NESTED_RANGE_PATH));
}
return (new Nested())
->setPath('search_data')
->setQuery($this->query);
->setQuery($query);
}
private function getNested(RangeFilterType|KeywordFilterType $filter, string $path): Nested
......
......@@ -6,20 +6,22 @@ namespace IQDEV\ElasticSearch\Converter\Request\Filter;
use IQDEV\ElasticSearch\Converter\Request\Filter\Type\KeywordFilterType;
use IQDEV\ElasticSearch\Converter\Request\Filter\Type\RangeFilterType;
use IQDEV\ElasticSearch\Request\Filter\Collection\FilterGroupCollection;
use IQDEV\ElasticSearch\Request\Filter\Filter;
use IQDEV\ElasticSearch\Criteria\Filter\Collection\FilterGroupCollection;
use IQDEV\ElasticSearch\Criteria\Filter\Filter;
use IQDEV\ElasticSearch\Search\BoolQuery\Query;
class PropertyFilter extends AbstractFilterQuery
{
public function getQuery(FilterGroupCollection $filterGroupCollection, array $exclude = []): Query
{
$query = new Query();
$keywordFiltersGroup = $filterGroupCollection->getKeywordFilters($exclude);
foreach ($keywordFiltersGroup as $keywordFilter) {
/** @var Filter $keywordFilter */
$esableFilter = new KeywordFilterType($keywordFilter);
$this->setFilterByLogic($filterGroupCollection->getLogicOperator(), $esableFilter->getEsable());
$this->setFilterByLogic($query, $filterGroupCollection->getLogicOperator(), $esableFilter->getEsable());
}
$rangeFilterGroup = $filterGroupCollection->getRangeFilters($exclude);
......@@ -28,9 +30,9 @@ class PropertyFilter extends AbstractFilterQuery
/** @var FilterGroupCollection $filterGroup */
$esableFilter = new RangeFilterType($filterGroup);
$this->setFilterByLogic($filterGroupCollection->getLogicOperator(), $esableFilter->getEsable());
$this->setFilterByLogic($query, $filterGroupCollection->getLogicOperator(), $esableFilter->getEsable());
}
return $this->query;
return $query;
}
}
......@@ -5,7 +5,7 @@ declare(strict_types=1);
namespace IQDEV\ElasticSearch\Converter\Request\Filter\Type;
use IQDEV\ElasticSearch\Esable;
use IQDEV\ElasticSearch\Request\Filter\Filter;
use IQDEV\ElasticSearch\Criteria\Filter\Filter;
use IQDEV\ElasticSearch\Search\BoolQuery\Terms;
class KeywordFilterType extends AbstractFilterType
......
......@@ -5,9 +5,9 @@ declare(strict_types=1);
namespace IQDEV\ElasticSearch\Converter\Request\Filter\Type;
use IQDEV\ElasticSearch\Esable;
use IQDEV\ElasticSearch\Request\Filter\Collection\FilterCollection;
use IQDEV\ElasticSearch\Request\Filter\Collection\FilterGroupCollection;
use IQDEV\ElasticSearch\Request\Filter\Filter;
use IQDEV\ElasticSearch\Criteria\Filter\Collection\FilterCollection;
use IQDEV\ElasticSearch\Criteria\Filter\Collection\FilterGroupCollection;
use IQDEV\ElasticSearch\Criteria\Filter\Filter;
use IQDEV\ElasticSearch\Search\BoolQuery\Stats;
class RangeFilterType extends AbstractFilterType
......