From dd21837e0513b2783a3501d9d274ea7a974a5fe5 Mon Sep 17 00:00:00 2001 From: Nikita Chernykh Date: Wed, 27 Sep 2023 15:11:57 +0500 Subject: [PATCH] Escape dependence --- composer.json | 12 +-- .../Converter/CriteriaToEsRequest.php | 42 ++++------ .../Converter/EsResponseToResult.php | 16 ++-- src/ElasticSearch/Criteria.php | 35 ++++++++ src/ElasticSearch/Document/Product.php | 21 +++++ .../Document/ProductCollection.php | 17 ++++ .../Document/Property/AttrType.php | 30 +++++++ .../Document/Property/PropertyType.php | 40 +++++++++ src/ElasticSearch/Document/Property/Type.php | 13 +++ src/ElasticSearch/Facet/Facet.php | 35 +++++++- src/ElasticSearch/Facet/FacetCollection.php | 4 +- src/ElasticSearch/Facet/FacetKeyword.php | 8 +- src/ElasticSearch/Facet/FacetNumber.php | 2 +- src/ElasticSearch/Facet/FacetTypeEnum.php | 9 ++ src/ElasticSearch/Facet/Facetable.php | 9 ++ src/ElasticSearch/Facet/Item/FacetItem.php | 39 +++++++++ .../Facet/Item/FacetItemCollection.php | 14 ++++ .../Facet/Item/FacetItemList.php | 24 ++++++ .../Facet/Item/FacetItemRange.php | 55 +++++++++++++ .../Facet/Item/FacetItemRangeDTO.php | 22 +++++ .../Facet/Item/FacetItemSingle.php | 18 ++++ src/ElasticSearch/Facet/NewFacet.php | 15 ++++ .../Facet/Type/FacetListType.php | 7 ++ .../Facet/Type/FacetRangeType.php | 7 ++ src/ElasticSearch/Facet/Type/FacetType.php | 7 ++ src/ElasticSearch/Filter/Field.php | 18 ++++ src/ElasticSearch/Filter/Filter.php | 36 ++++++++ src/ElasticSearch/Filter/FilterCollection.php | 55 +++++++++++++ .../Filter/FilterGroupCollection.php | 82 +++++++++++++++++++ src/ElasticSearch/Filter/FilterKeyword.php | 25 ++++++ src/ElasticSearch/Filter/FilterNumber.php | 23 ++++++ src/ElasticSearch/Filter/FilterOperator.php | 48 +++++++++++ src/ElasticSearch/Filter/FilterType.php | 52 ++++++++++++ src/ElasticSearch/Filter/FilterValue.php | 8 ++ src/ElasticSearch/Filter/LogicOperator.php | 47 +++++++++++ .../Filter/PostFilterCollection.php | 2 - .../Filter/QueryFilterCollection.php | 2 - .../Indexer/BaseIndexProvider.php | 3 +- src/ElasticSearch/Order/Order.php | 24 +++++- .../Order/OrderKeywordProperty.php | 2 +- .../Order/OrderNumberProperty.php | 2 +- src/ElasticSearch/Pagination.php | 15 ++++ src/ElasticSearch/Query/SearchQuery.php | 15 ++++ .../Query/SearchQueryHandler.php | 22 +++++ .../Query/SearchQueryResponse.php | 15 ++++ src/ElasticSearch/Result.php | 39 +++++++++ .../Search/BoolQuery/FilterNumberFacet.php | 2 +- src/ElasticSearch/SearchService.php | 4 +- src/ElasticSearch/Searchable.php | 13 +++ tests/{FIlter => Filter}/AggsTest.php | 20 ++--- .../CommonRangeKeywordsTest.php | 18 ++-- tests/{FIlter => Filter}/IndexesTest.php | 4 +- tests/{FIlter => Filter}/KeywordsTest.php | 16 ++-- .../QueryAndPostFilterTest.php | 20 ++--- tests/{FIlter => Filter}/QueryTest.php | 18 ++-- tests/{FIlter => Filter}/RangeTest.php | 14 ++-- tests/{FIlter => Filter}/SearchItemsTest.php | 16 ++-- tests/{FIlter => Filter}/SortTest.php | 24 +++--- tests/Helpers/FormatData.php | 14 ++-- tests/Seed/DefaultSeed.php | 4 +- tests/Service/SearchClient.php | 2 +- 61 files changed, 1072 insertions(+), 153 deletions(-) create mode 100644 src/ElasticSearch/Criteria.php create mode 100644 src/ElasticSearch/Document/Product.php create mode 100644 src/ElasticSearch/Document/ProductCollection.php create mode 100644 src/ElasticSearch/Document/Property/AttrType.php create mode 100644 src/ElasticSearch/Document/Property/PropertyType.php create mode 100644 src/ElasticSearch/Document/Property/Type.php create mode 100644 src/ElasticSearch/Facet/FacetTypeEnum.php create mode 100644 src/ElasticSearch/Facet/Facetable.php create mode 100644 src/ElasticSearch/Facet/Item/FacetItem.php create mode 100644 src/ElasticSearch/Facet/Item/FacetItemCollection.php create mode 100644 src/ElasticSearch/Facet/Item/FacetItemList.php create mode 100644 src/ElasticSearch/Facet/Item/FacetItemRange.php create mode 100644 src/ElasticSearch/Facet/Item/FacetItemRangeDTO.php create mode 100644 src/ElasticSearch/Facet/Item/FacetItemSingle.php create mode 100644 src/ElasticSearch/Facet/NewFacet.php create mode 100644 src/ElasticSearch/Facet/Type/FacetListType.php create mode 100644 src/ElasticSearch/Facet/Type/FacetRangeType.php create mode 100644 src/ElasticSearch/Facet/Type/FacetType.php create mode 100644 src/ElasticSearch/Filter/Field.php create mode 100644 src/ElasticSearch/Filter/Filter.php create mode 100644 src/ElasticSearch/Filter/FilterCollection.php create mode 100644 src/ElasticSearch/Filter/FilterGroupCollection.php create mode 100644 src/ElasticSearch/Filter/FilterKeyword.php create mode 100644 src/ElasticSearch/Filter/FilterNumber.php create mode 100644 src/ElasticSearch/Filter/FilterOperator.php create mode 100644 src/ElasticSearch/Filter/FilterType.php create mode 100644 src/ElasticSearch/Filter/FilterValue.php create mode 100644 src/ElasticSearch/Filter/LogicOperator.php create mode 100644 src/ElasticSearch/Pagination.php create mode 100644 src/ElasticSearch/Query/SearchQuery.php create mode 100644 src/ElasticSearch/Query/SearchQueryHandler.php create mode 100644 src/ElasticSearch/Query/SearchQueryResponse.php create mode 100644 src/ElasticSearch/Result.php create mode 100644 src/ElasticSearch/Searchable.php rename tests/{FIlter => Filter}/AggsTest.php (98%) rename tests/{FIlter => Filter}/CommonRangeKeywordsTest.php (90%) rename tests/{FIlter => Filter}/IndexesTest.php (97%) rename tests/{FIlter => Filter}/KeywordsTest.php (94%) rename tests/{FIlter => Filter}/QueryAndPostFilterTest.php (99%) rename tests/{FIlter => Filter}/QueryTest.php (97%) rename tests/{FIlter => Filter}/RangeTest.php (96%) rename tests/{FIlter => Filter}/SearchItemsTest.php (94%) rename tests/{FIlter => Filter}/SortTest.php (91%) diff --git a/composer.json b/composer.json index 2362612..1f0b16f 100644 --- a/composer.json +++ b/composer.json @@ -16,9 +16,8 @@ "php" ], "require": { - "php": ">=7.4", + "php": ">=8.1", "ramsey/collection": "^1.2", - "iqdev/search-dc": "1.2.*", "elasticsearch/elasticsearch": "^8.5", "vlucas/phpdotenv": "^5.4.1" }, @@ -32,15 +31,8 @@ "IQDEV\\ElasticSearchTests\\": "tests/" } }, - "repositories": [ - { - "type": "vcs", - "url": "ssh://git@gitlab.iqdev.digital:8422/piligrimov/search-dc.git" - } - ], "require-dev": { - "phpunit/phpunit": "^9.5", - "symfony/var-dumper": "^5.4" + "phpunit/phpunit": "^9.5" }, "scripts": { "tests": "php ./vendor/bin/phpunit --testdox --verbose" diff --git a/src/ElasticSearch/Converter/CriteriaToEsRequest.php b/src/ElasticSearch/Converter/CriteriaToEsRequest.php index 0150585..c168286 100644 --- a/src/ElasticSearch/Converter/CriteriaToEsRequest.php +++ b/src/ElasticSearch/Converter/CriteriaToEsRequest.php @@ -4,8 +4,6 @@ namespace IQDEV\ElasticSearch\Converter; use IQDEV\ElasticSearch\Filter\PostFilterCollection; use IQDEV\ElasticSearch\Filter\QueryFilterCollection; -use IQDEV\ElasticSearch\Order\OrderAscType; -use IQDEV\ElasticSearch\Order\OrderDescType; use IQDEV\ElasticSearch\Order\OrderField; use IQDEV\ElasticSearch\Order\OrderKeywordProperty; use IQDEV\ElasticSearch\Order\OrderNumberProperty; @@ -19,20 +17,18 @@ use IQDEV\ElasticSearch\Search\BoolQuery\Terms; use IQDEV\ElasticSearch\Search\Nested; use IQDEV\ElasticSearch\Search\Pagination; use IQDEV\ElasticSearch\Search\Request; -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\FilterKeyword; -use IQDEV\Search\Filter\FilterNumber; -use IQDEV\Search\Filter\FilterOperator; -use IQDEV\Search\Filter\FilterType; -use IQDEV\Search\Filter\LogicOperator; -use IQDEV\Search\Order\Order; -use IQDEV\Search\Order\OrderAscType as SOrderAscType; -use IQDEV\Search\Order\OrderDescType as SOrderDescType; +use IQDEV\ElasticSearch\Criteria; +use IQDEV\ElasticSearch\Document\Property\AttrType; +use IQDEV\ElasticSearch\Document\Property\PropertyType; +use IQDEV\ElasticSearch\Filter\Filter; +use IQDEV\ElasticSearch\Filter\FilterCollection; +use IQDEV\ElasticSearch\Filter\FilterGroupCollection; +use IQDEV\ElasticSearch\Filter\FilterKeyword; +use IQDEV\ElasticSearch\Filter\FilterNumber; +use IQDEV\ElasticSearch\Filter\FilterOperator; +use IQDEV\ElasticSearch\Filter\FilterType; +use IQDEV\ElasticSearch\Filter\LogicOperator; +use IQDEV\ElasticSearch\Order\Order; final class CriteriaToEsRequest { @@ -66,22 +62,16 @@ final class CriteriaToEsRequest foreach ($criteria->sorting() as $order) { /** @var Order $order */ - $direction = null; - if ($order->orderType() instanceof SOrderAscType) { - $direction = new OrderAscType(); - } - if ($order->orderType() instanceof SOrderDescType) { - $direction = new OrderDescType(); - } + $direction = $order->orderType(); if ($order->orderBy() instanceof AttrType) { - $request->getSort()->add(new OrderField($order->orderBy()->key(), $direction)); + $request->getSort()->add(new OrderField($order->orderBy(), $direction)); } elseif ($order->orderBy() instanceof PropertyType) { if ($order->orderBy()->type() === PropertyType::TYPE_KEYWORD) { - $request->getSort()->add(new OrderKeywordProperty($order->orderBy()->key(), $direction)); + $request->getSort()->add(new OrderKeywordProperty($order->orderBy(), $direction)); } elseif ($order->orderBy()->type() === PropertyType::TYPE_NUMBER) { - $request->getSort()->add(new OrderNumberProperty($order->orderBy()->key(), $direction)); + $request->getSort()->add(new OrderNumberProperty($order->orderBy(), $direction)); } } } diff --git a/src/ElasticSearch/Converter/EsResponseToResult.php b/src/ElasticSearch/Converter/EsResponseToResult.php index 6d734f1..ee1262c 100644 --- a/src/ElasticSearch/Converter/EsResponseToResult.php +++ b/src/ElasticSearch/Converter/EsResponseToResult.php @@ -3,14 +3,14 @@ namespace IQDEV\ElasticSearch\Converter; use Elastic\Elasticsearch\Response\Elasticsearch; -use IQDEV\Search\Document\Product; -use IQDEV\Search\Facet\Facet; -use IQDEV\Search\Facet\Item\FacetItemList; -use IQDEV\Search\Facet\Item\FacetItemRange; -use IQDEV\Search\Facet\Item\FacetItemRangeDTO; -use IQDEV\Search\Facet\Type\FacetListType; -use IQDEV\Search\Facet\Type\FacetRangeType; -use IQDEV\Search\Result; +use IQDEV\ElasticSearch\Document\Product; +use IQDEV\ElasticSearch\Facet\Facet; +use IQDEV\ElasticSearch\Facet\Item\FacetItemList; +use IQDEV\ElasticSearch\Facet\Item\FacetItemRange; +use IQDEV\ElasticSearch\Facet\Item\FacetItemRangeDTO; +use IQDEV\ElasticSearch\Facet\Type\FacetListType; +use IQDEV\ElasticSearch\Facet\Type\FacetRangeType; +use IQDEV\ElasticSearch\Result; final class EsResponseToResult { diff --git a/src/ElasticSearch/Criteria.php b/src/ElasticSearch/Criteria.php new file mode 100644 index 0000000..524d590 --- /dev/null +++ b/src/ElasticSearch/Criteria.php @@ -0,0 +1,35 @@ +filters = new FilterCollection(); + $this->sorting = new OrderCollection(); + $this->pagination = new Pagination(); + } + + public function filters(): FilterCollection + { + return $this->filters; + } + + public function sorting(): OrderCollection + { + return $this->sorting; + } + + public function pagination(): Pagination + { + return $this->pagination; + } +} diff --git a/src/ElasticSearch/Document/Product.php b/src/ElasticSearch/Document/Product.php new file mode 100644 index 0000000..0bac9a8 --- /dev/null +++ b/src/ElasticSearch/Document/Product.php @@ -0,0 +1,21 @@ +id = $id; + $this->title = $title; + $this->info = $info; + } +} diff --git a/src/ElasticSearch/Document/ProductCollection.php b/src/ElasticSearch/Document/ProductCollection.php new file mode 100644 index 0000000..85db7a0 --- /dev/null +++ b/src/ElasticSearch/Document/ProductCollection.php @@ -0,0 +1,17 @@ + + */ +final class ProductCollection extends AbstractCollection +{ + + public function getType(): string + { + return Product::class; + } +} diff --git a/src/ElasticSearch/Document/Property/AttrType.php b/src/ElasticSearch/Document/Property/AttrType.php new file mode 100644 index 0000000..246828d --- /dev/null +++ b/src/ElasticSearch/Document/Property/AttrType.php @@ -0,0 +1,30 @@ +key = $key; + $this->type = $type; + } + + public function key(): string + { + return $this->key; + } + + public function type(): ?string + { + return $this->type; + } + + public static function types(): array + { + return []; + } +} \ No newline at end of file diff --git a/src/ElasticSearch/Document/Property/PropertyType.php b/src/ElasticSearch/Document/Property/PropertyType.php new file mode 100644 index 0000000..f533c51 --- /dev/null +++ b/src/ElasticSearch/Document/Property/PropertyType.php @@ -0,0 +1,40 @@ +key = $key; + $this->type = $type; + } + + public function key(): string + { + return $this->key; + } + + public function type(): string + { + return $this->type; + } + + public static function types(): array + { + return [ + self::TYPE_NUMBER, + self::TYPE_KEYWORD, + ]; + } +} diff --git a/src/ElasticSearch/Document/Property/Type.php b/src/ElasticSearch/Document/Property/Type.php new file mode 100644 index 0000000..9469944 --- /dev/null +++ b/src/ElasticSearch/Document/Property/Type.php @@ -0,0 +1,13 @@ +type = $type; + $this->code = $code; + $this->products = new FacetItemCollection(); + } + + public function getType(): FacetType + { + return $this->type; + } + + public function getCode(): string + { + return $this->code; + } + + public function es(): array + { + return [ + 'facet_code' => $this->code, + 'facet_value' => $this->type, + ]; + } } diff --git a/src/ElasticSearch/Facet/FacetCollection.php b/src/ElasticSearch/Facet/FacetCollection.php index e84af39..d628b75 100644 --- a/src/ElasticSearch/Facet/FacetCollection.php +++ b/src/ElasticSearch/Facet/FacetCollection.php @@ -9,11 +9,11 @@ final class FacetCollection extends AbstractCollection implements Esable { public function getType(): string { - return Facet::class; + return Facetable::class; } public function es(): array { - return array_map(static fn(Facet $facet) => $facet->es(), $this->toArray()); + return array_map(static fn(Facetable $facet) => $facet->es(), $this->toArray()); } } diff --git a/src/ElasticSearch/Facet/FacetKeyword.php b/src/ElasticSearch/Facet/FacetKeyword.php index fc43162..11fd094 100644 --- a/src/ElasticSearch/Facet/FacetKeyword.php +++ b/src/ElasticSearch/Facet/FacetKeyword.php @@ -2,16 +2,16 @@ namespace IQDEV\ElasticSearch\Facet; -final class FacetKeyword implements Facet +final class FacetKeyword implements Facetable { private string $key; - /** @var string|string[] */ - private $value; + /** @var string|array */ + private string|array $value; /** * @param string|string[] $value */ - public function __construct(string $key, $value) + public function __construct(string $key, string|array $value) { $this->key = $key; $this->value = $value; diff --git a/src/ElasticSearch/Facet/FacetNumber.php b/src/ElasticSearch/Facet/FacetNumber.php index 953dfca..12bf983 100644 --- a/src/ElasticSearch/Facet/FacetNumber.php +++ b/src/ElasticSearch/Facet/FacetNumber.php @@ -2,7 +2,7 @@ namespace IQDEV\ElasticSearch\Facet; -final class FacetNumber implements Facet +final class FacetNumber implements Facetable { private string $key; private float $value; diff --git a/src/ElasticSearch/Facet/FacetTypeEnum.php b/src/ElasticSearch/Facet/FacetTypeEnum.php new file mode 100644 index 0000000..e0491c7 --- /dev/null +++ b/src/ElasticSearch/Facet/FacetTypeEnum.php @@ -0,0 +1,9 @@ +label; + } + + public function getValue(): ?string + { + return $this->value; + } + + public function getCount(): int + { + return $this->count; + } + + public function isActive(): bool + { + return $this->count > 0; + } + + public function isSelected(): bool + { + return $this->selected; + } +} diff --git a/src/ElasticSearch/Facet/Item/FacetItemCollection.php b/src/ElasticSearch/Facet/Item/FacetItemCollection.php new file mode 100644 index 0000000..9e3a0d0 --- /dev/null +++ b/src/ElasticSearch/Facet/Item/FacetItemCollection.php @@ -0,0 +1,14 @@ +value = $value; + $instance->label = $label; + $instance->count = $count; + $instance->selected = $selected; + + return $instance; + } +} diff --git a/src/ElasticSearch/Facet/Item/FacetItemRange.php b/src/ElasticSearch/Facet/Item/FacetItemRange.php new file mode 100644 index 0000000..7289941 --- /dev/null +++ b/src/ElasticSearch/Facet/Item/FacetItemRange.php @@ -0,0 +1,55 @@ +label = $label; + $instance->count = $count; + $instance->selected = $selected; + + $instance->data = $data; + $instance->selectedData = $selectedData; + + return $instance; + } + + public function getFullRange(): array + { + return [ + 'min' => $this->data->min, + 'max' => $this->data->max + ]; + } + + public function getSelectedRange(): array + { + return [ + 'min' => $this->selectedData->min, + 'max' => $this->selectedData->max + ]; + } + + public function getData(): FacetItemRangeDTO + { + return $this->data; + } + + public function getSelectedData(): FacetItemRangeDTO + { + return $this->selectedData; + } +} diff --git a/src/ElasticSearch/Facet/Item/FacetItemRangeDTO.php b/src/ElasticSearch/Facet/Item/FacetItemRangeDTO.php new file mode 100644 index 0000000..a3fd7fe --- /dev/null +++ b/src/ElasticSearch/Facet/Item/FacetItemRangeDTO.php @@ -0,0 +1,22 @@ +min = $min; + $instance->max = $max; + $instance->avg = $avg; + $instance->sum = $sum; + + return $instance; + } +} \ No newline at end of file diff --git a/src/ElasticSearch/Facet/Item/FacetItemSingle.php b/src/ElasticSearch/Facet/Item/FacetItemSingle.php new file mode 100644 index 0000000..255858c --- /dev/null +++ b/src/ElasticSearch/Facet/Item/FacetItemSingle.php @@ -0,0 +1,18 @@ +value = $value; + $instance->count = $count; + $instance->label = $label; + + return $instance; + } +} diff --git a/src/ElasticSearch/Facet/NewFacet.php b/src/ElasticSearch/Facet/NewFacet.php new file mode 100644 index 0000000..cc08955 --- /dev/null +++ b/src/ElasticSearch/Facet/NewFacet.php @@ -0,0 +1,15 @@ +value = $value; + } + + public function value(): string + { + return $this->value; + } +} diff --git a/src/ElasticSearch/Filter/Filter.php b/src/ElasticSearch/Filter/Filter.php new file mode 100644 index 0000000..97b26f1 --- /dev/null +++ b/src/ElasticSearch/Filter/Filter.php @@ -0,0 +1,36 @@ +field = $field; + $this->operator = $operator; + $this->value = $value; + } + + public function field(): Field + { + return $this->field; + } + + public function operator(): FilterOperator + { + return $this->operator; + } + + public function value(): FilterValue + { + return $this->value; + } +} diff --git a/src/ElasticSearch/Filter/FilterCollection.php b/src/ElasticSearch/Filter/FilterCollection.php new file mode 100644 index 0000000..7bb1d49 --- /dev/null +++ b/src/ElasticSearch/Filter/FilterCollection.php @@ -0,0 +1,55 @@ +type = new LogicOperator(LogicOperator::AND); + } + + /** + * @inheritDoc + */ + public function getType(): string + { + return FilterGroupCollection::class; + } + + /** + * Установка типа логической операции + * + * @param LogicOperator $type + * + * @return $this + */ + public function setLogicalType(LogicOperator $type): self + { + $this->type = $type; + + return $this; + } + + /** + * Получение типа логической операции + * + * @return LogicOperator + */ + public function getLogicalType(): LogicOperator + { + return $this->type; + } +} diff --git a/src/ElasticSearch/Filter/FilterGroupCollection.php b/src/ElasticSearch/Filter/FilterGroupCollection.php new file mode 100644 index 0000000..5bbce1e --- /dev/null +++ b/src/ElasticSearch/Filter/FilterGroupCollection.php @@ -0,0 +1,82 @@ +type = new LogicOperator(LogicOperator::AND); + $this->filterType = FilterType::post(); + } + + /** + * @inheritDoc + */ + public function getType(): string + { + return Filter::class; + } + + /** + * Установка типа логической операции + * + * @param LogicOperator $type + * + * @return $this + */ + public function setLogicalType(LogicOperator $type): self + { + $this->type = $type; + + return $this; + } + + /** + * Получение типа логической операции + * + * @return LogicOperator + */ + public function getLogicalType(): LogicOperator + { + return $this->type; + } + + /** + * Установка типа фильтрации + * + * @param FilterType $type + * + * @return $this + */ + public function setFilterType(FilterType $type): self + { + $this->filterType = $type; + + return $this; + } + + /** + * Получение типа фильтрации + * + * @return FilterType + */ + public function getFilterType(): FilterType + { + return $this->filterType; + } +} diff --git a/src/ElasticSearch/Filter/FilterKeyword.php b/src/ElasticSearch/Filter/FilterKeyword.php new file mode 100644 index 0000000..d3edd61 --- /dev/null +++ b/src/ElasticSearch/Filter/FilterKeyword.php @@ -0,0 +1,25 @@ +value = $value; + } + + /** + * @return string|string[] + */ + public function value() + { + return $this->value; + } +} diff --git a/src/ElasticSearch/Filter/FilterNumber.php b/src/ElasticSearch/Filter/FilterNumber.php new file mode 100644 index 0000000..7a9dc75 --- /dev/null +++ b/src/ElasticSearch/Filter/FilterNumber.php @@ -0,0 +1,23 @@ +value = $value; + } + + public function value(): float + { + return $this->value; + } +} diff --git a/src/ElasticSearch/Filter/FilterOperator.php b/src/ElasticSearch/Filter/FilterOperator.php new file mode 100644 index 0000000..a7d34c4 --- /dev/null +++ b/src/ElasticSearch/Filter/FilterOperator.php @@ -0,0 +1,48 @@ +'; + const LT = '<'; + const GTE = '>='; + const LTE = '<='; + const CONTAINS = 'CONTAINS'; + const NOT_CONTAINS = 'NOT_CONTAINS'; + + private string $operator; + + public function __construct(string $operator) + { + if (!in_array($operator, self::toArray(), true)) { + throw new \InvalidArgumentException(sprintf('invalid operator %s', $operator)); + } + + $this->operator = $operator; + } + + public function value(): string + { + return $this->operator; + } + + /** + * @return string[] + */ + public static function toArray(): array + { + return [ + self::EQ, + self::NE, + self::GT, + self::LT, + self::GTE, + self::LTE, + self::CONTAINS, + self::NOT_CONTAINS, + ]; + } +} diff --git a/src/ElasticSearch/Filter/FilterType.php b/src/ElasticSearch/Filter/FilterType.php new file mode 100644 index 0000000..732db06 --- /dev/null +++ b/src/ElasticSearch/Filter/FilterType.php @@ -0,0 +1,52 @@ +operator = $operator; + } + + public function value(): string + { + return $this->operator; + } + + /** + * @return string[] + */ + public static function toArray(): array + { + return [ + self::POST, + self::QUERY + ]; + } + + public static function __callStatic($method, $arguments) + { + if (in_array($method, self::toArray())) { + return new self($method); + } + } +} diff --git a/src/ElasticSearch/Filter/FilterValue.php b/src/ElasticSearch/Filter/FilterValue.php new file mode 100644 index 0000000..611f15d --- /dev/null +++ b/src/ElasticSearch/Filter/FilterValue.php @@ -0,0 +1,8 @@ +operator = $operator; + } + + public function value(): string + { + return $this->operator; + } + + /** + * @return string[] + */ + public static function toArray(): array + { + return [ + self::AND, + self::OR + ]; + } + + public static function __callStatic($method, $arguments) + { + $method = strtoupper($method); + if (in_array($method, self::toArray())) { + return new self($method); + } + } +} diff --git a/src/ElasticSearch/Filter/PostFilterCollection.php b/src/ElasticSearch/Filter/PostFilterCollection.php index 315d43a..8b677a7 100644 --- a/src/ElasticSearch/Filter/PostFilterCollection.php +++ b/src/ElasticSearch/Filter/PostFilterCollection.php @@ -2,8 +2,6 @@ namespace IQDEV\ElasticSearch\Filter; -use IQDEV\Search\Filter\FilterCollection; - class PostFilterCollection extends FilterCollection { } \ No newline at end of file diff --git a/src/ElasticSearch/Filter/QueryFilterCollection.php b/src/ElasticSearch/Filter/QueryFilterCollection.php index ec72fe0..aa700cc 100644 --- a/src/ElasticSearch/Filter/QueryFilterCollection.php +++ b/src/ElasticSearch/Filter/QueryFilterCollection.php @@ -2,8 +2,6 @@ namespace IQDEV\ElasticSearch\Filter; -use IQDEV\Search\Filter\FilterCollection; - class QueryFilterCollection extends FilterCollection { } \ No newline at end of file diff --git a/src/ElasticSearch/Indexer/BaseIndexProvider.php b/src/ElasticSearch/Indexer/BaseIndexProvider.php index 2a5aee2..83df733 100644 --- a/src/ElasticSearch/Indexer/BaseIndexProvider.php +++ b/src/ElasticSearch/Indexer/BaseIndexProvider.php @@ -6,7 +6,6 @@ use IQDEV\ElasticSearch\Configuration; use IQDEV\ElasticSearch\Document\ProductDocument; use IQDEV\ElasticSearch\Facet\FacetCategory; use IQDEV\ElasticSearch\Facet\FacetKeyword; -use IQDEV\ElasticSearch\Facet\FacetNumber; class BaseIndexProvider implements IndexProvider { @@ -29,7 +28,7 @@ class BaseIndexProvider implements IndexProvider foreach ($product['properties'] as $type => $values) { foreach ($values as $key => $prop) { if ($type === 'number') { - $document->getNumberFacets()->add(new FacetNumber($key, $prop)); + $document->getNumberFacets()->add(new FacetKeyword($key, $prop)); } else { $document->getKeywordFacets()->add(new FacetKeyword($key, $prop)); } diff --git a/src/ElasticSearch/Order/Order.php b/src/ElasticSearch/Order/Order.php index b23f067..82d4ac8 100644 --- a/src/ElasticSearch/Order/Order.php +++ b/src/ElasticSearch/Order/Order.php @@ -3,14 +3,15 @@ namespace IQDEV\ElasticSearch\Order; use IQDEV\ElasticSearch\Esable; +use IQDEV\ElasticSearch\Document\Property\Type; -abstract class Order implements Esable +class Order implements Esable { - public string $by; + public Type $by; public OrderType $direction; public array $properties; - public function __construct(string $by, OrderType $direction, array $properties = []) + public function __construct(Type $by, OrderType $direction, array $properties = []) { $this->by = $by; $this->direction = $direction; @@ -19,6 +20,21 @@ abstract class Order implements Esable public function es(): array { - return array_merge([$this->by => $this->direction::getType()], $this->properties); + return array_merge([$this->by->key() => $this->direction::getType()], $this->properties); + } + + public function orderBy(): Type + { + return $this->by; + } + + public function orderType(): OrderType + { + return $this->direction; + } + + public function orderProperties(): array + { + return $this->properties; } } diff --git a/src/ElasticSearch/Order/OrderKeywordProperty.php b/src/ElasticSearch/Order/OrderKeywordProperty.php index c490062..f0ae3e1 100644 --- a/src/ElasticSearch/Order/OrderKeywordProperty.php +++ b/src/ElasticSearch/Order/OrderKeywordProperty.php @@ -14,7 +14,7 @@ class OrderKeywordProperty extends Order 'bool' => [ 'must' => [ 'term' => [ - 'search_data.keyword_facet.facet_code' => $this->by, + 'search_data.keyword_facet.facet_code' => $this->by->key(), ] ], ], diff --git a/src/ElasticSearch/Order/OrderNumberProperty.php b/src/ElasticSearch/Order/OrderNumberProperty.php index befc546..b6a1401 100644 --- a/src/ElasticSearch/Order/OrderNumberProperty.php +++ b/src/ElasticSearch/Order/OrderNumberProperty.php @@ -14,7 +14,7 @@ class OrderNumberProperty extends Order 'bool' => [ 'must' => [ 'term' => [ - 'search_data.number_facet.facet_code' => $this->by, + 'search_data.number_facet.facet_code' => $this->by->key(), ] ], ], diff --git a/src/ElasticSearch/Pagination.php b/src/ElasticSearch/Pagination.php new file mode 100644 index 0000000..3fc99c1 --- /dev/null +++ b/src/ElasticSearch/Pagination.php @@ -0,0 +1,15 @@ +limit = $limit; + $this->offset = $offset; + } +} diff --git a/src/ElasticSearch/Query/SearchQuery.php b/src/ElasticSearch/Query/SearchQuery.php new file mode 100644 index 0000000..f23a42f --- /dev/null +++ b/src/ElasticSearch/Query/SearchQuery.php @@ -0,0 +1,15 @@ +criteria = $criteria; + } +} diff --git a/src/ElasticSearch/Query/SearchQueryHandler.php b/src/ElasticSearch/Query/SearchQueryHandler.php new file mode 100644 index 0000000..a105066 --- /dev/null +++ b/src/ElasticSearch/Query/SearchQueryHandler.php @@ -0,0 +1,22 @@ +searchService = $searchService; + } + + public function handle(SearchQuery $q): SearchQueryResponse + { + $result = $this->searchService->search($q->criteria); + + return new SearchQueryResponse($result); + } +} diff --git a/src/ElasticSearch/Query/SearchQueryResponse.php b/src/ElasticSearch/Query/SearchQueryResponse.php new file mode 100644 index 0000000..f1dca39 --- /dev/null +++ b/src/ElasticSearch/Query/SearchQueryResponse.php @@ -0,0 +1,15 @@ +result = $result; + } +} diff --git a/src/ElasticSearch/Result.php b/src/ElasticSearch/Result.php new file mode 100644 index 0000000..54bc776 --- /dev/null +++ b/src/ElasticSearch/Result.php @@ -0,0 +1,39 @@ +products = new ProductCollection(); + $this->facets = new FacetCollection(); + } + + public function setTotal(int $total): void + { + $this->total = $total; + } + + public function getTotal(): int + { + return $this->total; + } + + public function getProducts(): ProductCollection + { + return $this->products; + } + + public function getFacets(): FacetCollection + { + return $this->facets; + } +} diff --git a/src/ElasticSearch/Search/BoolQuery/FilterNumberFacet.php b/src/ElasticSearch/Search/BoolQuery/FilterNumberFacet.php index b150931..2b3985b 100644 --- a/src/ElasticSearch/Search/BoolQuery/FilterNumberFacet.php +++ b/src/ElasticSearch/Search/BoolQuery/FilterNumberFacet.php @@ -4,7 +4,7 @@ namespace IQDEV\ElasticSearch\Search\BoolQuery; use IQDEV\ElasticSearch\Esable; use IQDEV\ElasticSearch\Search\Nested; -use IQDEV\Search\Filter\FilterOperator; +use IQDEV\ElasticSearch\Filter\FilterOperator; final class FilterNumberFacet implements Esable { diff --git a/src/ElasticSearch/SearchService.php b/src/ElasticSearch/SearchService.php index a1319b9..fcc5476 100644 --- a/src/ElasticSearch/SearchService.php +++ b/src/ElasticSearch/SearchService.php @@ -7,10 +7,8 @@ use Elastic\Elasticsearch\Exception\ClientResponseException; use Elastic\Elasticsearch\Exception\ServerResponseException; use IQDEV\ElasticSearch\Converter\CriteriaToEsRequest; use IQDEV\ElasticSearch\Converter\EsResponseToResult; -use IQDEV\Search\Criteria; -use IQDEV\Search\Result; -class SearchService implements \IQDEV\Search\SearchService +class SearchService implements Searchable { private Client $esClient; private Configuration $configuration; diff --git a/src/ElasticSearch/Searchable.php b/src/ElasticSearch/Searchable.php new file mode 100644 index 0000000..b47bed5 --- /dev/null +++ b/src/ElasticSearch/Searchable.php @@ -0,0 +1,13 @@ +indexRunner = new IndexRunner( $this->esClient, $this->configuration, - new TestLogger() + new NullLogger() ); } diff --git a/tests/FIlter/KeywordsTest.php b/tests/Filter/KeywordsTest.php similarity index 94% rename from tests/FIlter/KeywordsTest.php rename to tests/Filter/KeywordsTest.php index 51acdf6..df62a19 100644 --- a/tests/FIlter/KeywordsTest.php +++ b/tests/Filter/KeywordsTest.php @@ -5,14 +5,14 @@ namespace IQDEV\ElasticSearchTests\Filter; 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; -use IQDEV\Search\Filter\FilterGroupCollection; -use IQDEV\Search\Filter\FilterKeyword; -use IQDEV\Search\Filter\FilterOperator; -use IQDEV\Search\Filter\FilterType; -use IQDEV\Search\Query\SearchQuery; +use IQDEV\ElasticSearch\Criteria; +use IQDEV\ElasticSearch\Filter\Field; +use IQDEV\ElasticSearch\Filter\Filter; +use IQDEV\ElasticSearch\Filter\FilterGroupCollection; +use IQDEV\ElasticSearch\Filter\FilterKeyword; +use IQDEV\ElasticSearch\Filter\FilterOperator; +use IQDEV\ElasticSearch\Filter\FilterType; +use IQDEV\ElasticSearch\Query\SearchQuery; class KeywordsTest extends AbstractTestCase { diff --git a/tests/FIlter/QueryAndPostFilterTest.php b/tests/Filter/QueryAndPostFilterTest.php similarity index 99% rename from tests/FIlter/QueryAndPostFilterTest.php rename to tests/Filter/QueryAndPostFilterTest.php index dcf6fff..9ea7ecc 100644 --- a/tests/FIlter/QueryAndPostFilterTest.php +++ b/tests/Filter/QueryAndPostFilterTest.php @@ -5,16 +5,16 @@ namespace IQDEV\ElasticSearchTests\Filter; 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; -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; -use IQDEV\Search\Query\SearchQuery; +use IQDEV\ElasticSearch\Criteria; +use IQDEV\ElasticSearch\Filter\Field; +use IQDEV\ElasticSearch\Filter\Filter; +use IQDEV\ElasticSearch\Filter\FilterGroupCollection; +use IQDEV\ElasticSearch\Filter\FilterKeyword; +use IQDEV\ElasticSearch\Filter\FilterNumber; +use IQDEV\ElasticSearch\Filter\FilterOperator; +use IQDEV\ElasticSearch\Filter\FilterType; +use IQDEV\ElasticSearch\Filter\LogicOperator; +use IQDEV\ElasticSearch\Query\SearchQuery; class QueryAndPostFilterTest extends AbstractTestCase { diff --git a/tests/FIlter/QueryTest.php b/tests/Filter/QueryTest.php similarity index 97% rename from tests/FIlter/QueryTest.php rename to tests/Filter/QueryTest.php index df79ee2..2db833a 100644 --- a/tests/FIlter/QueryTest.php +++ b/tests/Filter/QueryTest.php @@ -6,15 +6,15 @@ 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; -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\Query\SearchQuery; +use IQDEV\ElasticSearch\Criteria; +use IQDEV\ElasticSearch\Filter\Field; +use IQDEV\ElasticSearch\Filter\Filter; +use IQDEV\ElasticSearch\Filter\FilterGroupCollection; +use IQDEV\ElasticSearch\Filter\FilterKeyword; +use IQDEV\ElasticSearch\Filter\FilterNumber; +use IQDEV\ElasticSearch\Filter\FilterOperator; +use IQDEV\ElasticSearch\Filter\FilterType; +use IQDEV\ElasticSearch\Query\SearchQuery; /** * Тестирование агрегирующих функций diff --git a/tests/FIlter/RangeTest.php b/tests/Filter/RangeTest.php similarity index 96% rename from tests/FIlter/RangeTest.php rename to tests/Filter/RangeTest.php index b9f6726..9c9b032 100644 --- a/tests/FIlter/RangeTest.php +++ b/tests/Filter/RangeTest.php @@ -5,13 +5,13 @@ namespace IQDEV\ElasticSearchTests\Filter; 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; -use IQDEV\Search\Filter\FilterGroupCollection; -use IQDEV\Search\Filter\FilterNumber; -use IQDEV\Search\Filter\FilterOperator; -use IQDEV\Search\Query\SearchQuery; +use IQDEV\ElasticSearch\Criteria; +use IQDEV\ElasticSearch\Filter\Field; +use IQDEV\ElasticSearch\Filter\Filter; +use IQDEV\ElasticSearch\Filter\FilterGroupCollection; +use IQDEV\ElasticSearch\Filter\FilterNumber; +use IQDEV\ElasticSearch\Filter\FilterOperator; +use IQDEV\ElasticSearch\Query\SearchQuery; class RangeTest extends AbstractTestCase { diff --git a/tests/FIlter/SearchItemsTest.php b/tests/Filter/SearchItemsTest.php similarity index 94% rename from tests/FIlter/SearchItemsTest.php rename to tests/Filter/SearchItemsTest.php index 7f53c91..5327213 100644 --- a/tests/FIlter/SearchItemsTest.php +++ b/tests/Filter/SearchItemsTest.php @@ -5,14 +5,14 @@ namespace IQDEV\ElasticSearchTests\Filter; 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; -use IQDEV\Search\Filter\FilterGroupCollection; -use IQDEV\Search\Filter\FilterKeyword; -use IQDEV\Search\Filter\FilterOperator; -use IQDEV\Search\Filter\FilterType; -use IQDEV\Search\Query\SearchQuery; +use IQDEV\ElasticSearch\Criteria; +use IQDEV\ElasticSearch\Filter\Field; +use IQDEV\ElasticSearch\Filter\Filter; +use IQDEV\ElasticSearch\Filter\FilterGroupCollection; +use IQDEV\ElasticSearch\Filter\FilterKeyword; +use IQDEV\ElasticSearch\Filter\FilterOperator; +use IQDEV\ElasticSearch\Filter\FilterType; +use IQDEV\ElasticSearch\Query\SearchQuery; class SearchItemsTest extends AbstractTestCase { diff --git a/tests/FIlter/SortTest.php b/tests/Filter/SortTest.php similarity index 91% rename from tests/FIlter/SortTest.php rename to tests/Filter/SortTest.php index a7a28d9..9d4b445 100644 --- a/tests/FIlter/SortTest.php +++ b/tests/Filter/SortTest.php @@ -2,16 +2,18 @@ namespace IQDEV\ElasticSearchTests\Filter; +use IQDEV\ElasticSearch\Order\OrderAscType; +use IQDEV\ElasticSearch\Order\OrderDescType; +use IQDEV\ElasticSearch\Order\OrderKeywordProperty; +use IQDEV\ElasticSearch\Order\OrderNumberProperty; use IQDEV\ElasticSearchTests\AbstractTestCase; use IQDEV\ElasticSearchTests\Helpers\FormatData; use IQDEV\ElasticSearchTests\Service\SearchClient; -use IQDEV\Search\Criteria; -use IQDEV\Search\Document\Property\AttrType; -use IQDEV\Search\Document\Property\PropertyType; -use IQDEV\Search\Order\Order; -use IQDEV\Search\Order\OrderAscType; -use IQDEV\Search\Order\OrderDescType; -use IQDEV\Search\Query\SearchQuery; +use IQDEV\ElasticSearch\Criteria; +use IQDEV\ElasticSearch\Document\Property\AttrType; +use IQDEV\ElasticSearch\Document\Property\PropertyType; +use IQDEV\ElasticSearch\Order\Order; +use IQDEV\ElasticSearch\Query\SearchQuery; class SortTest extends AbstractTestCase { @@ -96,7 +98,7 @@ class SortTest extends AbstractTestCase { $criteria = new Criteria(); - $criteria->sorting()->add(new Order( + $criteria->sorting()->add(new OrderKeywordProperty( new PropertyType('color', PropertyType::TYPE_KEYWORD), new OrderAscType(), )); @@ -132,7 +134,7 @@ class SortTest extends AbstractTestCase { $criteria = new Criteria(); - $criteria->sorting()->add(new Order( + $criteria->sorting()->add(new OrderKeywordProperty( new PropertyType('color', PropertyType::TYPE_KEYWORD), new OrderDescType(), )); @@ -168,7 +170,7 @@ class SortTest extends AbstractTestCase { $criteria = new Criteria(); - $criteria->sorting()->add(new Order( + $criteria->sorting()->add(new OrderNumberProperty( new PropertyType('price', PropertyType::TYPE_NUMBER), new OrderAscType(), )); @@ -204,7 +206,7 @@ class SortTest extends AbstractTestCase { $criteria = new Criteria(); - $criteria->sorting()->add(new Order( + $criteria->sorting()->add(new OrderNumberProperty( new PropertyType('price', PropertyType::TYPE_NUMBER), new OrderDescType(), )); diff --git a/tests/Helpers/FormatData.php b/tests/Helpers/FormatData.php index f042c9a..7914eed 100644 --- a/tests/Helpers/FormatData.php +++ b/tests/Helpers/FormatData.php @@ -2,13 +2,13 @@ namespace IQDEV\ElasticSearchTests\Helpers; -use IQDEV\Search\Document\Product; -use IQDEV\Search\Facet\Facet; -use IQDEV\Search\Facet\Item\FacetItemList; -use IQDEV\Search\Facet\Item\FacetItemRange; -use IQDEV\Search\Facet\Type\FacetListType; -use IQDEV\Search\Facet\Type\FacetRangeType; -use IQDEV\Search\Result; +use IQDEV\ElasticSearch\Document\Product; +use IQDEV\ElasticSearch\Facet\Facet; +use IQDEV\ElasticSearch\Facet\Item\FacetItemList; +use IQDEV\ElasticSearch\Facet\Item\FacetItemRange; +use IQDEV\ElasticSearch\Facet\Type\FacetListType; +use IQDEV\ElasticSearch\Facet\Type\FacetRangeType; +use IQDEV\ElasticSearch\Result; class FormatData { diff --git a/tests/Seed/DefaultSeed.php b/tests/Seed/DefaultSeed.php index 8ab1eea..fac4092 100644 --- a/tests/Seed/DefaultSeed.php +++ b/tests/Seed/DefaultSeed.php @@ -7,7 +7,7 @@ use IQDEV\ElasticSearch\Configuration; use IQDEV\ElasticSearch\Indexer\IndexRunner; use IQDEV\ElasticSearchTests\Factory\ClientFactory; use IQDEV\ElasticSearchTests\Helpers\TestIndexProvider; -use Psr\Log\Test\TestLogger; +use Psr\Log\NullLogger; class DefaultSeed { @@ -22,7 +22,7 @@ class DefaultSeed $this->indexRunner = new IndexRunner( ClientFactory::create(), $this->configuration, - new TestLogger() + new NullLogger() ); } diff --git a/tests/Service/SearchClient.php b/tests/Service/SearchClient.php index bb3d57a..ea73a5b 100644 --- a/tests/Service/SearchClient.php +++ b/tests/Service/SearchClient.php @@ -5,7 +5,7 @@ namespace IQDEV\ElasticSearchTests\Service; use IQDEV\ElasticSearch\SearchService; use IQDEV\ElasticSearch\Config\BaseConfiguration as Configuration; use IQDEV\ElasticSearchTests\Factory\ClientFactory; -use IQDEV\Search\Query\SearchQueryHandler; +use IQDEV\ElasticSearch\Query\SearchQueryHandler; class SearchClient { -- GitLab