Commit 2656b229 authored by Vadim Galizyanov's avatar Vadim Galizyanov
Browse files

Added tests for query and post filter

parent 1f4c9fe1
Loading
Loading
Loading
Loading
+48 −43
Original line number Diff line number Diff line
@@ -25,6 +25,8 @@ 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\FilterKeyword;
use IQDEV\Search\Filter\FilterNumber;
use IQDEV\Search\Filter\FilterOperator;
use IQDEV\Search\Filter\FilterType;
use IQDEV\Search\Filter\LogicOperator;
@@ -176,6 +178,9 @@ final class CriteriaToEsRequest
    {
        $numberFilter = new Query();

        if ($filterCollection->isEmpty()) {
            return $numberFilter;
        }
        $ranges = [];

        foreach ($filterCollection as $filterGroup) {
@@ -229,6 +234,11 @@ final class CriteriaToEsRequest
    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()) {
@@ -299,24 +309,16 @@ final class CriteriaToEsRequest
            )
        );

        [$queryFilters, $postFilters] = $this->groupFilters($criteria->filters());

        $getKey = static fn(string $type, string $name): string => sprintf('%s_facet_%s', $type, $name);
        foreach ($criteria->filters() as $filterGroup) {
        foreach ($postFilters 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
                )
                ) {
                if ($filter->value() instanceof FilterNumber) {
                    continue;
                }

@@ -332,6 +334,7 @@ final class CriteriaToEsRequest
                    continue;
                }

                if ($filter->value() instanceof FilterKeyword) {
                    $aggsFiltered = new Aggs($getKey('keyword', $field));
                    $aggsFiltered->addAggs(
                        AggsFacetTerms::create(
@@ -340,8 +343,9 @@ final class CriteriaToEsRequest
                        )
                    );
                    $queryKeywordFiltered = new Query();
                $keywordFilter        = $this->getKeywordFilter($criteria->filters(), [$field]);
                $numberFilter         = $this->getNumberFilter($criteria->filters());

                    $keywordFilter        = $this->getKeywordFilter($postFilters, [$field]);
                    $numberFilter         = $this->getNumberFilter($postFilters);
                    if (false === $keywordFilter->isEmpty()) {
                        $nestedFilterKeyword = new Nested();
                        $nestedFilterKeyword->setPath('search_data')
@@ -364,9 +368,11 @@ final class CriteriaToEsRequest

                    $request->getAggs()->add($aggsFiltered);
                }
            }
        }

            $keywordFilter = $this->getKeywordFilter($criteria->filters());
            $numberFilter  = $this->getNumberFilter($criteria->filters());
            $keywordFilter = $this->getKeywordFilter($postFilters);
            $numberFilter  = $this->getNumberFilter($postFilters);

            $aggsKeywordFiltered = new Aggs('keyword_facet_filtered');
            $aggsKeywordFiltered->addAggs(
@@ -419,7 +425,6 @@ final class CriteriaToEsRequest
            $request->getAggs()
                ->add($aggsKeywordFiltered)
                ->add($aggsNumberFiltered);
        }

        return $request;
    }
+93 −82
Original line number Diff line number Diff line
@@ -35,6 +35,31 @@ final class EsResponseToResult
        }

        if (isset($data['aggregations']['keyword_facet']['agg_keyword_facet_code']['buckets'])) {
            $this->parseKeywordFacet($data, $catalogSearchResult);
        }

        if (isset($data['aggregations']['number_facet']['agg_number_facet_code']['buckets'])) {
            $this->parseNumberFacet($data, $catalogSearchResult);
        }

        return $catalogSearchResult;
    }

    private function productFromArray(array $data): Product
    {
        if (!isset($data['data']['id'])) {
            throw new \RuntimeException('id is not set');
        }
        $id = $data['data']['id'];

        $title = $data['data']['title'] ?? '';
        $info = $data;

        return new Product($id, $title, $info);
    }

    private function parseKeywordFacet(array $data, Result $catalogSearchResult)
    {
        $buckets = $data['aggregations']['keyword_facet']['agg_keyword_facet_code']['buckets'];
        $bucketsFiltered = [];
        if (isset($data['aggregations']['keyword_facet_filtered']['all_keyword_facet_filtered']['agg_keyword_facet_code']['buckets'])) {
@@ -61,6 +86,7 @@ final class EsResponseToResult
        }
        $bucketsFiltered = array_filter($bucketsFiltered);


        foreach ($buckets as $bucket) {
            $code = $bucket['key'];
            $valueBucket = $bucket['agg_keyword_facet_value']['buckets'];
@@ -87,7 +113,8 @@ final class EsResponseToResult
        }
    }

        if (isset($data['aggregations']['number_facet']['agg_number_facet_code']['buckets'])) {
    private function parseNumberFacet(array $data, Result $catalogSearchResult)
    {
        $buckets = $data['aggregations']['number_facet']['agg_number_facet_code']['buckets'];
        $bucketsFiltered = [];

@@ -124,20 +151,4 @@ final class EsResponseToResult
            $catalogSearchResult->getFacets()->add($facet);
        }
    }

        return $catalogSearchResult;
    }

    private function productFromArray(array $data): Product
    {
        if (!isset($data['data']['id'])) {
            throw new \RuntimeException('id is not set');
        }
        $id = $data['data']['id'];

        $title = $data['data']['title'] ?? '';
        $info = $data;

        return new Product($id, $title, $info);
    }
}
+649 −0

File added.

Preview size limit exceeded, changes collapsed.

+154 −0
Original line number Diff line number Diff line
@@ -4,6 +4,8 @@ namespace IQDEV\ElasticSearchTests\Filter;

use IQDEV\ElasticSearch\Converter\CriteriaToEsRequest;
use IQDEV\ElasticSearchTests\AbstractTestCase;
use IQDEV\ElasticSearchTests\Helpers\FormatData;
use IQDEV\ElasticSearchTests\Service\SearchClient;
use IQDEV\Search\Criteria;
use IQDEV\Search\Filter\Field;
use IQDEV\Search\Filter\Filter;
@@ -12,6 +14,7 @@ use IQDEV\Search\Filter\FilterKeyword;
use IQDEV\Search\Filter\FilterNumber;
use IQDEV\Search\Filter\FilterOperator;
use IQDEV\Search\Filter\FilterType;
use IQDEV\Search\Query\SearchQuery;

/**
 * Тестирование агрегирующих функций
@@ -333,4 +336,155 @@ class QueryTest extends AbstractTestCase

        $this->assertArray($expected, $request->es());
    }

    public function testGlobalFilterPrice()
    {
        $filter = [
            'price' => [
                'key' => 'price',
                'min' => 105,
                'lower' => 103,
            ]
        ];

        $criteria = new Criteria();

        $filterCollectionPrice = new FilterGroupCollection([
            new Filter(
                new Field($filter['price']['key']),
                new FilterOperator(FilterOperator::GTE),
                new FilterNumber($filter['price']['min'])
            )
        ]);
        $criteria->filters()->add($filterCollectionPrice);


        $filterCollectionQueryPrice = new FilterGroupCollection([
            new Filter(
                new Field($filter['price']['key']),
                new FilterOperator(FilterOperator::GTE),
                new FilterNumber($filter['price']['lower'])
            ),
        ]);
        $filterCollectionQueryPrice->setFilterType(FilterType::query());
        $criteria->filters()->add($filterCollectionQueryPrice);

        $q = new SearchQuery($criteria);

        $handler = SearchClient::getInstance();
        $result = $handler->handle($q)->result;

        $expected = [
            'hits' => [
                'h2',
                'h3',
                'p1',
            ],
            "facets" => [
                0 => [
                    "code" => "brand",
                    "label" => null,
                    "type" => "list",
                    "items" => [
                        "list" => [
                            0 => [
                                "label" => null,
                                "value" => "nike",
                                "count" => 1,
                                "active" => true,
                            ],
                            1 => [
                                "label" => null,
                                "value" => "rebook",
                                "count" => 2,
                                "active" => true,
                            ]
                        ],
                        "range" => [],
                    ],
                ],
                1 => [
                    "code" => "color",
                    "label" => null,
                    "type" => "list",
                    "items" => [
                        "list" => [
                            0 => [
                                "label" => null,
                                "value" => "green",
                                "count" => 0,
                                "active" => false,
                            ],
                            1 => [
                                "label" => null,
                                "value" => "red",
                                "count" => 0,
                                "active" => false,
                            ],
                            2 => [
                                "label" => null,
                                "value" => "white",
                                "count" => 3,
                                "active" => true,
                            ],
                        ],
                        "range" => [],
                    ],
                ],
                2 => [
                    "code" => "size",
                    "label" => null,
                    "type" => "list",
                    "items" => [
                        "list" => [
                            0 => [
                                "label" => null,
                                "count" => 0,
                                "value" => "43",
                                "active" => false,
                            ],
                            1 => [
                                "label" => null,
                                "value" => "xl",
                                "count" => 2,
                                "active" => true,
                            ],
                            2 => [
                                "label" => null,
                                "value" => "xxl",
                                "count" => 1,
                                "active" => true,
                            ],
                        ],
                        "range" => [],
                    ],
                ],
                3 => [
                    "code" => "price",
                    "label" => null,
                    "type" => "range",
                    "items" => [
                        "list" => [],
                        "range" => [
                            0 => [
                                "label" => null,
                                "count" => 3,
                                "active" => true,
                                "fullRange" => [
                                    "min" => 103.0,
                                    "max" => 107.0,
                                ],
                                "activeRange" => [
                                    "min" => 105.0,
                                    "max" => 107.0,
                                ]
                            ]
                        ]
                    ]
                ]
            ]
        ];

        $this->assertEqualsCanonicalizing($expected, FormatData::formatDataWFacets($result));
    }
}
 No newline at end of file