diff --git a/src/ElasticSearch/Converter/Request/Aggregation/Aggregation.php b/src/ElasticSearch/Converter/Request/Aggregation/Aggregation.php index a9b6f64f95403eff2060a5be3d31862e8f6f1a41..0b54e4bed9697a4bd1a861f7446fe97533e003b3 100644 --- a/src/ElasticSearch/Converter/Request/Aggregation/Aggregation.php +++ b/src/ElasticSearch/Converter/Request/Aggregation/Aggregation.php @@ -41,23 +41,11 @@ class Aggregation $postFilterCollection = $this->criteria->getFilters()->getFilterCollectionByType(FilterType::POST); -// foreach ($postFilterCollection as $filterGroup) { -// /** @var FilterGroupCollection $filterGroup */ -// -// foreach ($filterGroup as $filter) { -// /** @var Filter $filter */ -// -// $filterAggregation = new FilterAggregation($this->configuration, $filter, $postFilterCollection); -// -// if ($aggregation = $filterAggregation->getFilterAggregation()) { -// $this->aggregations->add($aggregation); -// } -// } -// } - $fullAggregation = new FullAggregation($this->configuration, $postFilterCollection); + $filterAggregation = new FilterAggregation($this->configuration, $postFilterCollection->getKeywordFilters()); + $filterAggregation->updateRequestAggregation($this->aggregations); - $this->aggregations->add($fullAggregation->getKeywordAggregation()); - $this->aggregations->add($fullAggregation->getRangeAggregation()); + $fullAggregation = new FullAggregation($this->configuration, $postFilterCollection); + $fullAggregation->updateRequestAggregation($this->aggregations); } public function getAggregation(): AggsCollection diff --git a/src/ElasticSearch/Converter/Request/Aggregation/FilterAggregation.php b/src/ElasticSearch/Converter/Request/Aggregation/FilterAggregation.php index 9d3ff9e596c17a6a03e9ba726c5d5ee272739f64..ed1bf0aafc5a56397d9b06be4f2762fc90cae165 100644 --- a/src/ElasticSearch/Converter/Request/Aggregation/FilterAggregation.php +++ b/src/ElasticSearch/Converter/Request/Aggregation/FilterAggregation.php @@ -7,9 +7,11 @@ 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\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; @@ -20,57 +22,40 @@ class FilterAggregation public function __construct( private readonly Configuration $configuration, - private readonly Filter $filter, private readonly FilterCollection $filterCollection, ) { - if ($filter->value() instanceof FilterKeyword) { - $this->setAggregation(); - } } - private function setAggregation(): void + public function updateRequestAggregation(AggsCollection $original): void { - $this->aggregation = new Aggs( - $this->getKey('keyword', $this->filter->field()->value()) - ); + foreach ($this->filterCollection as $filterGroup) { + /** @var FilterGroupCollection $filterGroup */ - $this->aggregation->addAggs( - AggsFacetTerms::create( - 'agg_special', - 'keyword_facet' - ) - ); + foreach ($filterGroup as $filter) { + /** @var Filter $filter */ -// $queryKeywordFiltered = new Query(); -// -// $keywordFilterCollection = $this->filterCollection->getKeywordFilters([$this->filter->field()->value()]); -// $rangeFilterCollection = $this->filterCollection->getNumberFilters(); -// -// $keywordFilterQuery = (new FilterQuery($this->configuration, $keywordFilterCollection))->getQuery(); -// $rangeFilterQuery = (new FilterQuery($this->configuration, $rangeFilterCollection))->getQuery(); -// -// if (false === $keywordFilterQuery->isEmpty()) { -// foreach ($keywordFilterQuery->getFilter() as $filter) { -// $queryKeywordFiltered->getFilter()->add($filter); -// } -// } -// -// if (false === $rangeFilterQuery->isEmpty()) { -// foreach ($rangeFilterQuery->getFilter() as $filter) { -// $queryKeywordFiltered->getFilter()->add($filter); -// } -// } -// -// if ($queryKeywordFiltered->isEmpty() === false) { -// $this->aggregation->setQuery($queryKeywordFiltered); -// } else { -// $this->aggregation->setNested((new Nested())->setPath('search_data')); -// } - } + $field = $filter->field()->value(); - public function getFilterAggregation(): ?Aggs - { - return $this->aggregation; + $aggregation = new Aggs($this->getKey('keyword', $field)); + $aggregation->addAggs( + AggsFacetTerms::create( + 'agg_special', + 'keyword_facet' + ) + ); + + $queryFilterBuilder = new FilterQuery($this->configuration, $this->filterCollection, [$field]); + $query = $queryFilterBuilder->getQuery(); + + if (false === $query->isEmpty()) { + $aggregation->setQuery($query); + } else { + $aggregation->setNested((new Nested())->setPath('search_data')); + } + + $original->add($aggregation); + } + } } private function getKey(string $type, string $name): string diff --git a/src/ElasticSearch/Converter/Request/Aggregation/FullAggregation.php b/src/ElasticSearch/Converter/Request/Aggregation/FullAggregation.php index 7cad438825cb7d0f38bf0838e0878bbe689b0a63..1e00192d05807a0bc8af8a6413ec616514bb96c1 100644 --- a/src/ElasticSearch/Converter/Request/Aggregation/FullAggregation.php +++ b/src/ElasticSearch/Converter/Request/Aggregation/FullAggregation.php @@ -8,6 +8,7 @@ use IQDEV\ElasticSearch\Configuration; use IQDEV\ElasticSearch\Converter\Request\FilterQuery; use IQDEV\ElasticSearch\Request\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; @@ -23,20 +24,12 @@ class FullAggregation private readonly Configuration $configuration, private readonly FilterCollection $filterCollection, ) { - $this->queryKeywordFiltered = new Query(); - $this->queryNumberFiltered = new Query(); } - public function getKeywordAggregation(): Aggs + public function updateRequestAggregation(AggsCollection $original): void { - $filterCollection = $this->filterCollection->getKeywordFilters(); - $keywordFilter = (new FilterQuery($this->configuration, $filterCollection))->getQuery(); - - - if (isset($GLOBALS['DD']) && $GLOBALS['DD'] === true) { - dump($filterCollection); - dd($keywordFilter->es()); - } + $keywordQuery = (new FilterQuery($this->configuration, $this->filterCollection->getKeywordFilters()))->getQuery(); + $numberQuery = (new FilterQuery($this->configuration, $this->filterCollection->getNumberFilters()))->getQuery(); $aggsKeywordFiltered = new Aggs('keyword_facet_filtered'); $aggsKeywordFiltered->addAggs( @@ -46,13 +39,6 @@ class FullAggregation ) ); - return $aggsKeywordFiltered; - } - - public function getRangeAggregation(): Aggs - { - $filterCollection = $this->filterCollection->getNumberFilters(); - $aggsNumberFiltered = new Aggs('number_facet_filtered'); $aggsNumberFiltered->addAggs( AggsFacetStats::create( @@ -61,6 +47,30 @@ class FullAggregation ) ); - return $aggsNumberFiltered; + if (false === $keywordQuery->getFilter()->isEmpty()) { + foreach ($keywordQuery->getFilter() as $item) { + $numberQuery->getFilter()->add($item); + } + } + + if (false === $numberQuery->getFilter()->isEmpty()) { + foreach ($numberQuery->getFilter() as $item) { + $keywordQuery->getFilter()->add($item); + } + } + + if (false === $keywordQuery->getFilter()->isEmpty()) { + $aggsKeywordFiltered->setQuery($keywordQuery); + } else { + $aggsKeywordFiltered->setNested((new Nested())->setPath('search_data')); + } + + if (false === $numberQuery->getFilter()->isEmpty()) { + $aggsNumberFiltered->setQuery($numberQuery); + } else { + $aggsNumberFiltered->setNested((new Nested())->setPath('search_data')); + } + + $original->add($aggsKeywordFiltered)->add($aggsNumberFiltered); } } diff --git a/src/ElasticSearch/Converter/Request/CriteriaRequestBuilder.php b/src/ElasticSearch/Converter/Request/CriteriaRequestBuilder.php index 5f57182d617f6f500f6c1a2ec8cb593d4e167468..4a6f4338c0839a8cc0c09b152f4f737797bc1c4d 100644 --- a/src/ElasticSearch/Converter/Request/CriteriaRequestBuilder.php +++ b/src/ElasticSearch/Converter/Request/CriteriaRequestBuilder.php @@ -106,7 +106,7 @@ class CriteriaRequestBuilder extends RequestBuilder $request = clone $this->request; $filterQuery = new FilterQuery($this->configuration, $filterCollection); - $request->setQuery($filterQuery->getQuery()); + $request->getQuery()->modify($filterQuery->getQuery()); $this->request = $request; } @@ -116,7 +116,7 @@ class CriteriaRequestBuilder extends RequestBuilder $request = clone $this->request; $filterQuery = new FilterQuery($this->configuration, $filterCollection); - $request->setPostFilter($filterQuery->getQuery()); + $request->getPostFilter()->modify($filterQuery->getQuery()); $this->request = $request; } diff --git a/src/ElasticSearch/Converter/Request/Filter/AbstractFilterQuery.php b/src/ElasticSearch/Converter/Request/Filter/AbstractFilterQuery.php index f0a305acec5a9f859e0bcbad44d3495395e649c9..87eff1161e6203c76987da8d63636825bfe64b62 100644 --- a/src/ElasticSearch/Converter/Request/Filter/AbstractFilterQuery.php +++ b/src/ElasticSearch/Converter/Request/Filter/AbstractFilterQuery.php @@ -27,5 +27,5 @@ abstract class AbstractFilterQuery }; } - abstract public function getQuery(FilterGroupCollection $filterGroupCollection): Query|Nested; + abstract public function getQuery(FilterGroupCollection $filterGroupCollection, array $exclude): Query|Nested; } diff --git a/src/ElasticSearch/Converter/Request/Filter/NestedFilter.php b/src/ElasticSearch/Converter/Request/Filter/NestedFilter.php index f6796a59cdb63733e747a75a87fe8e40660051ad..d135ac6619c31a35f8d848d7cf7417d32502f4c9 100644 --- a/src/ElasticSearch/Converter/Request/Filter/NestedFilter.php +++ b/src/ElasticSearch/Converter/Request/Filter/NestedFilter.php @@ -17,9 +17,9 @@ class NestedFilter extends AbstractFilterQuery public const NESTED_RANGE_PATH = 'search_data.number_facet'; public const NESTED_KEYWORD_PATH = 'search_data.keyword_facet'; - public function getQuery(FilterGroupCollection $filterGroupCollection): Nested + public function getQuery(FilterGroupCollection $filterGroupCollection, array $exclude): Nested { - $keywordFiltersGroup = $filterGroupCollection->getKeywordFilters(); + $keywordFiltersGroup = $filterGroupCollection->getKeywordFilters($exclude); foreach ($keywordFiltersGroup as $keywordFilter) { /** @var Filter $keywordFilter */ $esableFilter = new KeywordFilterType($keywordFilter); @@ -27,7 +27,7 @@ class NestedFilter extends AbstractFilterQuery $this->setFilterByLogic($filterGroupCollection->getLogicOperator(), $this->getNested($esableFilter, self::NESTED_KEYWORD_PATH)); } - $rangeFilterGroup = $filterGroupCollection->getRangeFilters(); + $rangeFilterGroup = $filterGroupCollection->getRangeFilters($exclude); $rangesFilter = RangeFilterType::getFiltersByOneProperty($rangeFilterGroup); foreach ($rangesFilter as $filterGroup) { /** @var FilterGroupCollection $filterGroup */ diff --git a/src/ElasticSearch/Converter/Request/Filter/PropertyFilter.php b/src/ElasticSearch/Converter/Request/Filter/PropertyFilter.php index 536ebaf893969038336fdfea41e1662dfc4217c9..e78a5c3f8172eca8f1aeb85b4411002bb13828aa 100644 --- a/src/ElasticSearch/Converter/Request/Filter/PropertyFilter.php +++ b/src/ElasticSearch/Converter/Request/Filter/PropertyFilter.php @@ -12,9 +12,9 @@ use IQDEV\ElasticSearch\Search\BoolQuery\Query; class PropertyFilter extends AbstractFilterQuery { - public function getQuery(FilterGroupCollection $filterGroupCollection): Query + public function getQuery(FilterGroupCollection $filterGroupCollection, array $exclude = []): Query { - $keywordFiltersGroup = $filterGroupCollection->getKeywordFilters(); + $keywordFiltersGroup = $filterGroupCollection->getKeywordFilters($exclude); foreach ($keywordFiltersGroup as $keywordFilter) { /** @var Filter $keywordFilter */ $esableFilter = new KeywordFilterType($keywordFilter); @@ -22,7 +22,7 @@ class PropertyFilter extends AbstractFilterQuery $this->setFilterByLogic($filterGroupCollection->getLogicOperator(), $esableFilter->getEsable()); } - $rangeFilterGroup = $filterGroupCollection->getRangeFilters(); + $rangeFilterGroup = $filterGroupCollection->getRangeFilters($exclude); $rangesFilter = RangeFilterType::getFiltersByOneProperty($rangeFilterGroup); foreach ($rangesFilter as $filterGroup) { /** @var FilterGroupCollection $filterGroup */ diff --git a/src/ElasticSearch/Converter/Request/FilterQuery.php b/src/ElasticSearch/Converter/Request/FilterQuery.php index d9c297161586dcff1b024fd26475222ba5f89044..0e715d3226273af5e8e89f684ced7aa50af780cb 100644 --- a/src/ElasticSearch/Converter/Request/FilterQuery.php +++ b/src/ElasticSearch/Converter/Request/FilterQuery.php @@ -24,6 +24,7 @@ class FilterQuery public function __construct( private readonly Configuration $configuration, private readonly FilterCollection $filterCollection, + private array $exclude = [], ) { $this->query = new Query(); $this->convertToQuery(); @@ -48,9 +49,12 @@ class FilterQuery private function setQuery(FilterGroupCollection $filterGroup, AbstractFilterQuery $filterQuery): void { - $filters = $filterQuery->getQuery($filterGroup); - + $filters = $filterQuery->getQuery($filterGroup, $this->exclude); if ($filters instanceof Query) { + if ($filters->isEmpty()) { + return; + } + foreach ($filters->getFilter() as $filter) { $this->query->getFilter()->add($filter); } @@ -65,6 +69,10 @@ class FilterQuery $this->query = $filters; } elseif ($filters instanceof Nested) { + if ($filters->getQuery()->isEmpty()) { + return; + } + $this->query->getFilter()->add($filters); } } diff --git a/src/ElasticSearch/Criteria.php b/src/ElasticSearch/Criteria.php index d3b33865e3155c0b2b2f96d52fcc549098e43c0c..575d2ad9273a5c649a85ad484799a53c03ec427c 100644 --- a/src/ElasticSearch/Criteria.php +++ b/src/ElasticSearch/Criteria.php @@ -40,4 +40,12 @@ final class Criteria { return $this->pagination; } + + public function __clone(): void + { + $this->search = clone $this->search; + $this->filters = clone $this->filters; + $this->sorting = clone $this->sorting; + $this->pagination = clone $this->pagination; + } } diff --git a/src/ElasticSearch/Search/BoolQuery/Query.php b/src/ElasticSearch/Search/BoolQuery/Query.php index ff45c1a1a3a01f8de34d295bd5581400ff8f1f71..79047bbb18b96ccbd0c332ac69c3fb2ea733ca7e 100644 --- a/src/ElasticSearch/Search/BoolQuery/Query.php +++ b/src/ElasticSearch/Search/BoolQuery/Query.php @@ -118,4 +118,34 @@ final class Query implements Esable ], ]; } + + public function modify(Query $another): self + { + foreach ($another->getMust() as $item) { + $this->getMust()->add($item); + } + foreach ($another->getFilter() as $item) { + $this->getFilter()->add($item); + } + foreach ($another->getShould() as $item) { + $this->getShould()->add($item); + } + foreach ($another->getMustNot() as $item) { + $this->getMustNot()->add($item); + } + foreach ($another->getMatch() as $item) { + $this->getMatch()->add($item); + } + + return $this; + } + + public function __clone(): void + { + $this->must = clone $this->must; + $this->should = clone $this->should; + $this->filter = clone $this->filter; + $this->mustNot = clone $this->mustNot; + $this->match = clone $this->match; + } } diff --git a/src/ElasticSearch/SearchService.php b/src/ElasticSearch/SearchService.php index e3b70ce0b2c10144d1fe3ef2f0428ee67018fe6d..bac451786d711e026c291742b3a0d9a7aab6d777 100644 --- a/src/ElasticSearch/SearchService.php +++ b/src/ElasticSearch/SearchService.php @@ -29,6 +29,9 @@ class SearchService implements Searchable { $request = $this->criteriaToEsRequest->fromCriteria($criteria); + if (isset($GLOBALS['DD']) && $GLOBALS['DD'] === true) { + dd(json_encode($request->es())); + } $response = $this->esClient->search([ 'index' => $this->configuration->getIndexName(), 'body' => $request->es(), diff --git a/tests/Filter/AggsTest.php b/tests/Filter/AggsTest.php index 0de8e5b29e7a68458c554e330190c45ee79f0986..1d8a4f3886fd3d7e1b51969a91d23168d6892454 100644 --- a/tests/Filter/AggsTest.php +++ b/tests/Filter/AggsTest.php @@ -681,8 +681,6 @@ class AggsTest extends AbstractTestCase ) ])); - $GLOBALS['DD'] = true; - $q = new SearchQuery($criteria); $handler = SearchClient::getInstance(); diff --git a/tests/Filter/QueryAndPostFilterTest.php b/tests/Filter/QueryAndPostFilterTest.php index 88f682ac650463c17d60e06206a22e2fe5e661e1..c2f72f9de54da158f6e019c39666bddf4ffead7a 100644 --- a/tests/Filter/QueryAndPostFilterTest.php +++ b/tests/Filter/QueryAndPostFilterTest.php @@ -658,7 +658,6 @@ class QueryAndPostFilterTest extends AbstractTestCase ]); $criteria->getFilters()->add($filterCollectionColor); - $GLOBALS['DD'] = false; $q = new SearchQuery($criteria); $handler = SearchClient::getInstance(); $result = $handler->handle($q)->result; diff --git a/tests/Filter/QueryTest.php b/tests/Filter/QueryTest.php index 54eac8a468edbc88d42ce29ec2de13f8cfe3073b..ca4d22902a597095975fec3a6534adb97a95641d 100644 --- a/tests/Filter/QueryTest.php +++ b/tests/Filter/QueryTest.php @@ -101,7 +101,6 @@ class QueryTest extends AbstractTestCase $requestPost = $criteriaToEsRequest->fromCriteria($criteriaPost); $requestQuery = $criteriaToEsRequest->fromCriteria($criteriaQuery); - $expectedFilter = [ [ "nested" => [