From 5cab78436ba98ae37e9f2cc9af12f553f52fa2fa Mon Sep 17 00:00:00 2001 From: Pavel Piligrimov Date: Mon, 24 Apr 2023 12:32:15 +0500 Subject: [PATCH] update processing criteria --- composer.json | 2 +- .../Converter/CriteriaToEsRequest.php | 368 ++++++++++-------- 2 files changed, 199 insertions(+), 171 deletions(-) diff --git a/composer.json b/composer.json index 4ae5626..e95c6a6 100644 --- a/composer.json +++ b/composer.json @@ -18,7 +18,7 @@ "require": { "php": ">=7.4", "ramsey/collection": "^1.2", - "iqdev/search-dc": "1.1", + "iqdev/search-dc": "1.1.*", "elasticsearch/elasticsearch": "^8.5", "vlucas/phpdotenv": "^5.4.1" }, diff --git a/src/ElasticSearch/Converter/CriteriaToEsRequest.php b/src/ElasticSearch/Converter/CriteriaToEsRequest.php index 2c8e274..c14c426 100644 --- a/src/ElasticSearch/Converter/CriteriaToEsRequest.php +++ b/src/ElasticSearch/Converter/CriteriaToEsRequest.php @@ -21,7 +21,10 @@ use IQDEV\Search\Criteria; use IQDEV\Search\Document\Property\AttrType; use IQDEV\Search\Document\Property\PropertyType; use IQDEV\Search\FIlter\Filter; +use IQDEV\Search\Filter\FilterCollection; +use IQDEV\Search\Filter\FilterGroupCollection; use IQDEV\Search\Filter\FilterOperator; +use IQDEV\Search\Filter\LogicOperator; use IQDEV\Search\Order\Order; use IQDEV\Search\Order\OrderAscType as SOrderAscType; use IQDEV\Search\Order\OrderDescType as SOrderDescType; @@ -88,35 +91,38 @@ final class CriteriaToEsRequest return $request; } - foreach ($criteria->filters() as $filter) { - /** @var Filter $filter */ - $value = $filter->value()->value(); - $field = $filter->field()->value(); - - if ('search' === $field) { - if ($filter->operator()->value() === FilterOperator::CONTAINS) { - $request->addMatch( - 'suggest_search_content', - [ - 'query' => $value, - ], - ); - } else { - $request->addMatch( - 'full_search_content', - [ - 'query' => $value, - ], - ); + foreach ($criteria->filters() as $filterGroup) { + /** @var FilterGroupCollection $filterGroup */ + foreach ($filterGroup as $filter) { + /** @var Filter $filter */ + $value = $filter->value()->value(); + $field = $filter->field()->value(); + + if ('search' === $field) { + if ($filter->operator()->value() === FilterOperator::CONTAINS) { + $request->addMatch( + 'suggest_search_content', + [ + 'query' => $value, + ], + ); + } else { + $request->addMatch( + 'full_search_content', + [ + 'query' => $value, + ], + ); + } + continue; } - continue; - } - if ('category_id' === $field) { - $request->getQuery()->must( - new Terms('category_id', $filter->value()->value()) - ); - continue; + if ('category_id' === $field) { + $request->getQuery()->must( + new Terms('category_id', $filter->value()->value()) + ); + continue; + } } } @@ -147,32 +153,48 @@ final class CriteriaToEsRequest $ranges = []; - foreach ($criteria->filters() as $filter) { - /** @var Filter $filter */ - $value = $filter->value()->value(); - $field = $filter->field()->value(); - - if (in_array($field, $excludeFilter, true)) { + foreach ($criteria->filters() as $filterGroup) { + /** @var FilterGroupCollection $filterGroup */ + if ($filterGroup->isEmpty()) { continue; } - if (in_array($filter->operator()->value(), [FilterOperator::LT, FilterOperator::LTE], true)) { - $ranges[$field][$filter->operator()->value()] = $value; - continue; + $group = $filterGroup->getLogicalType()->value() === 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($filter->operator()->value(), [FilterOperator::GT, FilterOperator::GTE], true)) { - $ranges[$field][$filter->operator()->value()] = $value; + if (in_array($field, $excludeFilter, true)) { + continue; + } + if (in_array($filter->operator()->value(), [FilterOperator::LT, FilterOperator::LTE], true)) { + $ranges[$group][$field][$filter->operator()->value()] = $value; + continue; + } + + if (in_array($filter->operator()->value(), [FilterOperator::GT, FilterOperator::GTE], true)) { + $ranges[$group][$field][$filter->operator()->value()] = $value; + } } } if (false === empty($ranges)) { - foreach ($ranges as $field => $range) { - $numberFilter->filter( - new FilterNumberFacet( + foreach ($ranges as $iGroup => $group) { + foreach ($group as $field => $range) { + $facet = new FilterNumberFacet( $field, $range - ) - ); + ); + + if ($iGroup === 0) { + $numberFilter->filter($facet); + } else { + $numberFilter->should($facet); + } + } } } @@ -182,38 +204,41 @@ final class CriteriaToEsRequest private function getKeywordFilter(Criteria $criteria, array $excludeFilter = []): Query { $keywordFilter = new Query(); - foreach ($criteria->filters() as $filter) { - /** @var Filter $filter */ - $value = $filter->value()->value(); - $field = $filter->field()->value(); + foreach ($criteria->filters() as $filterGroup) { + /** @var FilterGroupCollection $filterGroup */ + 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($field, $excludeFilter, true)) { - continue; - } + if (in_array($filter->operator()->value(), [FilterOperator::LT, FilterOperator::LTE], true)) { + continue; + } - if (in_array($filter->operator()->value(), [FilterOperator::LT, FilterOperator::LTE], true)) { - continue; - } + if (in_array($filter->operator()->value(), [FilterOperator::GT, FilterOperator::GTE], true)) { + continue; + } - if (in_array($filter->operator()->value(), [FilterOperator::GT, FilterOperator::GTE], true)) { - continue; - } + if ('search' === $field) { + continue; + } - if ('search' === $field) { - continue; - } + if ('category_id' === $field) { + continue; + } - if ('category_id' === $field) { - continue; - } + if (is_array($value)) { + $value = array_map(static fn($v) => (string)$v, $value); + } else { + $value = (string)$value; + } - if (is_array($value)) { - $value = array_map(static fn($v) => (string)$v, $value); - } else { - $value = (string)$value; + $keywordFilter->filter(new FilterKeywordFacet($field, $value)); } - - $keywordFilter->filter(new FilterKeywordFacet($field, $value)); } return $keywordFilter; @@ -242,157 +267,160 @@ final class CriteriaToEsRequest ); $getKey = static fn(string $type, string $name): string => sprintf('%s_facet_%s', $type, $name); - foreach ($criteria->filters() as $filter) { - /** @var Filter $filter */ - $field = $filter->field()->value(); - - if (in_array( - $filter->operator()->value(), - [ - FilterOperator::LT, - FilterOperator::LTE, - FilterOperator::GT, - FilterOperator::GTE, - ], - true - ) - ) { - $aggsFiltered = new Aggs($getKey('number', $field)); + foreach ($criteria->filters() as $filterGroup) { + /** @var FilterGroupCollection $filterGroup */ + foreach ($filterGroup as $filter) { + /** @var Filter $filter */ + $field = $filter->field()->value(); + + if (in_array( + $filter->operator()->value(), + [ + FilterOperator::LT, + FilterOperator::LTE, + FilterOperator::GT, + FilterOperator::GTE, + ], + true + ) + ) { + $aggsFiltered = new Aggs($getKey('number', $field)); + $aggsFiltered->addAggs( + AggsFacetStats::create( + 'agg_special', + 'number_facet' + ) + ); + + $queryNumberFiltered = new Query(); + $keywordFilter = $this->getKeywordFilter($criteria); + $numberFilter = $this->getNumberFilter($criteria, [$field]); + + if (false === $keywordFilter->isEmpty()) { + $nestedFilterKeyword = new Nested(); + $nestedFilterKeyword->setPath('search_data') + ->setQuery($keywordFilter); + $queryNumberFiltered->filter($nestedFilterKeyword); + } + + if (false === $numberFilter->isEmpty()) { + $nestedFilterNumber = new Nested(); + $nestedFilterNumber->setPath('search_data') + ->setQuery($numberFilter); + $queryNumberFiltered->filter($nestedFilterNumber); + } + + if ($queryNumberFiltered->isEmpty() === false) { + $aggsFiltered->setQuery($queryNumberFiltered); + } else { + $aggsFiltered->setNested((new Nested())->setPath('search_data')); + } + + $request->getAggs()->add($aggsFiltered); + continue; + } + + if (in_array($filter->operator()->value(), [], true)) { + continue; + } + + if ('search' === $field) { + continue; + } + + if ('category_id' === $field) { + continue; + } + + $aggsFiltered = new Aggs($getKey('keyword', $field)); $aggsFiltered->addAggs( - AggsFacetStats::create( + AggsFacetTerms::create( 'agg_special', - 'number_facet' + 'keyword_facet' ) ); - - $queryNumberFiltered = new Query(); - $keywordFilter = $this->getKeywordFilter($criteria); - $numberFilter = $this->getNumberFilter($criteria, [$field]); - + $queryKeywordFiltered = new Query(); + $keywordFilter = $this->getKeywordFilter($criteria, [$field]); + $numberFilter = $this->getNumberFilter($criteria); if (false === $keywordFilter->isEmpty()) { $nestedFilterKeyword = new Nested(); $nestedFilterKeyword->setPath('search_data') ->setQuery($keywordFilter); - $queryNumberFiltered->filter($nestedFilterKeyword); + $queryKeywordFiltered->filter($nestedFilterKeyword); } if (false === $numberFilter->isEmpty()) { $nestedFilterNumber = new Nested(); $nestedFilterNumber->setPath('search_data') ->setQuery($numberFilter); - $queryNumberFiltered->filter($nestedFilterNumber); + $queryKeywordFiltered->filter($nestedFilterNumber); } - if ($queryNumberFiltered->isEmpty() === false) { - $aggsFiltered->setQuery($queryNumberFiltered); + if ($queryKeywordFiltered->isEmpty() === false) { + $aggsFiltered->setQuery($queryKeywordFiltered); } else { $aggsFiltered->setNested((new Nested())->setPath('search_data')); } $request->getAggs()->add($aggsFiltered); - continue; - } - - if (in_array($filter->operator()->value(), [], true)) { - continue; - } - - if ('search' === $field) { - continue; } - if ('category_id' === $field) { - continue; - } + $keywordFilter = $this->getKeywordFilter($criteria); + $numberFilter = $this->getNumberFilter($criteria); - $aggsFiltered = new Aggs($getKey('keyword', $field)); - $aggsFiltered->addAggs( + $aggsKeywordFiltered = new Aggs('keyword_facet_filtered'); + $aggsKeywordFiltered->addAggs( AggsFacetTerms::create( - 'agg_special', + 'all_keyword_facet_filtered', 'keyword_facet' ) ); $queryKeywordFiltered = new Query(); - $keywordFilter = $this->getKeywordFilter($criteria, [$field]); - $numberFilter = $this->getNumberFilter($criteria); + + $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->filter($nestedFilterKeyword); + $queryNumberFiltered->filter($nestedFilterKeyword); } if (false === $numberFilter->isEmpty()) { $nestedFilterNumber = new Nested(); $nestedFilterNumber->setPath('search_data') ->setQuery($numberFilter); + $queryKeywordFiltered->filter($nestedFilterNumber); + $queryNumberFiltered->filter($nestedFilterNumber); } - if ($queryKeywordFiltered->isEmpty() === false) { - $aggsFiltered->setQuery($queryKeywordFiltered); + if (false === $queryKeywordFiltered->isEmpty()) { + $aggsKeywordFiltered->setQuery($queryKeywordFiltered); } else { - $aggsFiltered->setNested((new Nested())->setPath('search_data')); + $aggsKeywordFiltered->setNested((new Nested())->setPath('search_data')); } - $request->getAggs()->add($aggsFiltered); - } - - $keywordFilter = $this->getKeywordFilter($criteria); - $numberFilter = $this->getNumberFilter($criteria); - - $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->filter($nestedFilterKeyword); - $queryNumberFiltered->filter($nestedFilterKeyword); - } - - if (false === $numberFilter->isEmpty()) { - $nestedFilterNumber = new Nested(); - $nestedFilterNumber->setPath('search_data') - ->setQuery($numberFilter); - - $queryKeywordFiltered->filter($nestedFilterNumber); - $queryNumberFiltered->filter($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')); + } - if (false === $queryNumberFiltered->isEmpty()) { - $aggsNumberFiltered->setQuery($queryNumberFiltered); - } else { - $aggsNumberFiltered->setNested((new Nested())->setPath('search_data')); + $request->getAggs() + ->add($aggsKeywordFiltered) + ->add($aggsNumberFiltered); } - $request->getAggs() - ->add($aggsKeywordFiltered) - ->add($aggsNumberFiltered); - return $request; } } -- GitLab