From 64324f41ca5c398b6f86b96e762bbcbf765467f6 Mon Sep 17 00:00:00 2001 From: Pavel Piligrimov <p.piligrimov@iqdev.digital> Date: Fri, 19 Jan 2024 03:54:37 +0500 Subject: [PATCH] aggs for properties of document --- src/ElasticSearch/Config/product.mappings.php | 6 +- .../Request/Aggregation/Aggregation.php | 52 ++-- .../Aggregation/PropertyAggregation.php | 55 ++++ .../Request/CriteriaRequestBuilder.php | 4 +- .../Converter/Result/EsResponseToResult.php | 33 +- src/ElasticSearch/Criteria/Aggs/Aggs.php | 20 ++ .../Criteria/Aggs/AggsCollection.php | 16 + src/ElasticSearch/Criteria/Criteria.php | 10 + .../Criteria/Filter/Value/FilterKeyword.php | 8 +- src/ElasticSearch/SearchService.php | 2 +- tests/Filter/AggsPropsTest.php | 281 ++++++++++++++++++ tests/Filter/IndexesTest.php | 4 +- tests/Filter/QueryTest.php | 145 ++++++++- tests/Helpers/TestIndexProvider.php | 5 +- tests/Seed/DefaultSeed.php | 18 +- 15 files changed, 623 insertions(+), 36 deletions(-) create mode 100644 src/ElasticSearch/Converter/Request/Aggregation/PropertyAggregation.php create mode 100644 src/ElasticSearch/Criteria/Aggs/Aggs.php create mode 100644 src/ElasticSearch/Criteria/Aggs/AggsCollection.php create mode 100644 tests/Filter/AggsPropsTest.php diff --git a/src/ElasticSearch/Config/product.mappings.php b/src/ElasticSearch/Config/product.mappings.php index bd51078..02ccb5d 100644 --- a/src/ElasticSearch/Config/product.mappings.php +++ b/src/ElasticSearch/Config/product.mappings.php @@ -20,7 +20,11 @@ return [ ], 'rating' => [ 'type' => 'double', - 'index' => false, + 'index' => true, + ], + 'new' => [ + 'type' => 'boolean', + 'index' => true ], 'popular' => [ 'type' => 'double', diff --git a/src/ElasticSearch/Converter/Request/Aggregation/Aggregation.php b/src/ElasticSearch/Converter/Request/Aggregation/Aggregation.php index 07b0fd2..3bee4a9 100644 --- a/src/ElasticSearch/Converter/Request/Aggregation/Aggregation.php +++ b/src/ElasticSearch/Converter/Request/Aggregation/Aggregation.php @@ -23,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); - $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 diff --git a/src/ElasticSearch/Converter/Request/Aggregation/PropertyAggregation.php b/src/ElasticSearch/Converter/Request/Aggregation/PropertyAggregation.php new file mode 100644 index 0000000..5fd4628 --- /dev/null +++ b/src/ElasticSearch/Converter/Request/Aggregation/PropertyAggregation.php @@ -0,0 +1,55 @@ +<?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); + } + } +} diff --git a/src/ElasticSearch/Converter/Request/CriteriaRequestBuilder.php b/src/ElasticSearch/Converter/Request/CriteriaRequestBuilder.php index cf4dc66..aa64a5a 100644 --- a/src/ElasticSearch/Converter/Request/CriteriaRequestBuilder.php +++ b/src/ElasticSearch/Converter/Request/CriteriaRequestBuilder.php @@ -40,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 diff --git a/src/ElasticSearch/Converter/Result/EsResponseToResult.php b/src/ElasticSearch/Converter/Result/EsResponseToResult.php index 008fe27..ce751a3 100644 --- a/src/ElasticSearch/Converter/Result/EsResponseToResult.php +++ b/src/ElasticSearch/Converter/Result/EsResponseToResult.php @@ -3,6 +3,7 @@ namespace IQDEV\ElasticSearch\Converter\Result; use Elastic\Elasticsearch\Response\Elasticsearch; +use IQDEV\ElasticSearch\Configuration; use IQDEV\ElasticSearch\Document\Product; use IQDEV\ElasticSearch\Facet\FacetResult; use IQDEV\ElasticSearch\Facet\FacetType; @@ -13,7 +14,7 @@ use IQDEV\ElasticSearch\Result; final class EsResponseToResult { - public function fromResponse(Elasticsearch $response): Result + public function fromResponse(Elasticsearch $response, Configuration $configuration): Result { $catalogSearchResult = new Result(); @@ -41,6 +42,8 @@ final class EsResponseToResult $this->parseNumberFacet($data, $catalogSearchResult); } + $this->parsePropertyFacet($data, $catalogSearchResult, $configuration); + return $catalogSearchResult; } @@ -97,6 +100,8 @@ final class EsResponseToResult if (isset($bucketsFiltered[$code][$value['key']])) { $count = $bucketsFiltered[$code][$value['key']]['doc_count']; + } elseif (isset($bucketsFiltered[$code])) { + $count = 0; } $facet->products->add( @@ -150,4 +155,30 @@ final class EsResponseToResult $catalogSearchResult->getFacets()->add($facet); } } + + private function parsePropertyFacet(array $data, Result $catalogSearchResult, Configuration $configuration) + { + $properties = array_keys($configuration->getMapping()['properties']); + + foreach ($data['aggregations'] as $key => $aggs) { + if (!in_array($key, $properties, true)) { + continue; + } + + $facet = new FacetResult(FacetType::LIST, $key); + $buckets = array_key_exists('buckets', $aggs) ? $aggs['buckets'] : $aggs[$key]['buckets']; + foreach ($buckets as $bucket) { + $code = $bucket['key']; + $count = $bucket['doc_count']; + + $facet->products->add( + FacetItemList::create( + $code, + $count + ) + ); + } + $catalogSearchResult->getFacets()->add($facet); + } + } } diff --git a/src/ElasticSearch/Criteria/Aggs/Aggs.php b/src/ElasticSearch/Criteria/Aggs/Aggs.php new file mode 100644 index 0000000..e2c71e6 --- /dev/null +++ b/src/ElasticSearch/Criteria/Aggs/Aggs.php @@ -0,0 +1,20 @@ +<?php + +declare(strict_types=1); + +namespace IQDEV\ElasticSearch\Criteria\Aggs; + +use IQDEV\ElasticSearch\Document\Property\Property; + +class Aggs +{ + public function __construct( + private readonly Property $property, + ) { + } + + public function getProperty(): Property + { + return $this->property; + } +} diff --git a/src/ElasticSearch/Criteria/Aggs/AggsCollection.php b/src/ElasticSearch/Criteria/Aggs/AggsCollection.php new file mode 100644 index 0000000..06aced2 --- /dev/null +++ b/src/ElasticSearch/Criteria/Aggs/AggsCollection.php @@ -0,0 +1,16 @@ +<?php + +namespace IQDEV\ElasticSearch\Criteria\Aggs; + +use Ramsey\Collection\AbstractCollection; + +class AggsCollection extends AbstractCollection +{ + /** + * @inheritDoc + */ + public function getType(): string + { + return Aggs::class; + } +} diff --git a/src/ElasticSearch/Criteria/Criteria.php b/src/ElasticSearch/Criteria/Criteria.php index ad59270..432834e 100644 --- a/src/ElasticSearch/Criteria/Criteria.php +++ b/src/ElasticSearch/Criteria/Criteria.php @@ -2,6 +2,7 @@ namespace IQDEV\ElasticSearch\Criteria; +use IQDEV\ElasticSearch\Criteria\Aggs\AggsCollection; use IQDEV\ElasticSearch\Criteria\Filter\Collection\FilterCollection; use IQDEV\ElasticSearch\Criteria\Order\OrderCollection; use IQDEV\ElasticSearch\Criteria\Search\SearchCollection; @@ -13,12 +14,15 @@ final class Criteria private OrderCollection $sorting; private Pagination $pagination; + private AggsCollection $aggregations; + public function __construct() { $this->search = new SearchCollection(); $this->filters = new FilterCollection(); $this->sorting = new OrderCollection(); $this->pagination = new Pagination(); + $this->aggregations = new AggsCollection(); } public function getSearch(): SearchCollection @@ -41,11 +45,17 @@ final class Criteria return $this->pagination; } + public function getAggs(): AggsCollection + { + return $this->aggregations; + } + public function __clone(): void { $this->search = clone $this->search; $this->filters = clone $this->filters; $this->sorting = clone $this->sorting; $this->pagination = clone $this->pagination; + $this->aggregations = clone $this->aggregations; } } diff --git a/src/ElasticSearch/Criteria/Filter/Value/FilterKeyword.php b/src/ElasticSearch/Criteria/Filter/Value/FilterKeyword.php index f012bf6..2d27c4d 100644 --- a/src/ElasticSearch/Criteria/Filter/Value/FilterKeyword.php +++ b/src/ElasticSearch/Criteria/Filter/Value/FilterKeyword.php @@ -7,17 +7,17 @@ use IQDEV\ElasticSearch\Criteria\Filter\FilterValue; class FilterKeyword implements FilterValue { /** - * @param string|string[] $value + * @param string|string[]|bool $value */ public function __construct( - public string|array $value + public string|array|bool $value ) { } /** - * @return string|string[] + * @return string|string[]|bool */ - public function value(): string|array + public function value(): string|array|bool { return $this->value; } diff --git a/src/ElasticSearch/SearchService.php b/src/ElasticSearch/SearchService.php index 356eb06..88b5537 100644 --- a/src/ElasticSearch/SearchService.php +++ b/src/ElasticSearch/SearchService.php @@ -35,6 +35,6 @@ class SearchService implements Searchable 'body' => $request->es(), ]); - return $this->esResponseToResult->fromResponse($response); + return $this->esResponseToResult->fromResponse($response, $this->configuration); } } diff --git a/tests/Filter/AggsPropsTest.php b/tests/Filter/AggsPropsTest.php new file mode 100644 index 0000000..253aaf9 --- /dev/null +++ b/tests/Filter/AggsPropsTest.php @@ -0,0 +1,281 @@ +<?php + +namespace IQDEV\ElasticSearchTests\Filter; + +use IQDEV\ElasticSearch\Criteria\Aggs\Aggs; +use IQDEV\ElasticSearch\Criteria\Criteria; +use IQDEV\ElasticSearch\Criteria\Filter\Collection\FilterGroupCollection; +use IQDEV\ElasticSearch\Criteria\Filter\Field; +use IQDEV\ElasticSearch\Criteria\Filter\Filter; +use IQDEV\ElasticSearch\Criteria\Filter\FilterOperator; +use IQDEV\ElasticSearch\Criteria\Filter\Value\FilterNumber; +use IQDEV\ElasticSearch\Criteria\Query\SearchQuery; +use IQDEV\ElasticSearch\Document\Property\Property; +use IQDEV\ElasticSearchTests\AbstractTestCase; +use IQDEV\ElasticSearchTests\Helpers\FormatData; +use IQDEV\ElasticSearchTests\Service\SearchClient; + +/** + * ТеÑтирование агрегирующих функций Ð´Ð»Ñ Ð¿Ñ€Ñмых ÑвойÑтв документов + */ +class AggsPropsTest extends AbstractTestCase +{ + public function testCategoryAggs() + { + $criteria = new Criteria(); + $criteria->getAggs()->add( + new Aggs( + new Property('new') + ) + ); + + $q = new SearchQuery($criteria); + + $handler = SearchClient::getInstance(); + $result = $handler->handle($q)->result; + + $expected = [ + 'hits' => [ + 'h1', + 'h2', + 'h3', + 'p1', + 's1', + 's2', + 's3', + 's4', + ], + 'facets' => [ + 0 => [ + 'code' => 'new', + 'label' => null, + 'type' => 'list', + 'items' => [ + 'list' => [ + 0 => [ + 'label' => null, + 'value' => 0, + 'count' => 3, + 'active' => true + ], + 1 => [ + 'label' => null, + 'value' => 1, + 'count' => 5, + 'active' => true + ] + ], + 'range' => [] + ] + ], + ] + ]; + + $this->assertEqualsCanonicalizing($expected, FormatData::formatDataWFacets($result)); + } + + public function testCategoryAggsWFilters() + { + $criteria = new Criteria(); + $criteria->getAggs()->add( + new Aggs( + new Property('new') + ) + ); + $criteria->getAggs()->add( + new Aggs( + new Property('rating') + ) + ); + + $filterCollectionPrice = new FilterGroupCollection([ + new Filter( + new Field('price'), + FilterOperator::GTE, + new FilterNumber(105) + ) + ]); + $criteria->getFilters()->add($filterCollectionPrice); + + $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' => 'adidas', + 'count' => 0, + 'active' => false + ], + 1 => [ + 'label' => null, + 'value' => 'nike', + 'count' => 1, + 'active' => true + ], + 3 => [ + 'label' => null, + 'value' => 'rebook', + 'count' => 2, + 'active' => true + ] + ], + 'range' => [] + ] + ], + 1 => [ + 'code' => 'color', + 'label' => null, + 'type' => 'list', + 'items' => [ + 'list' => [ + 0 => [ + 'label' => null, + 'value' => 'blue', + 'count' => 0, + 'active' => false + ], + 1 => [ + 'label' => null, + 'value' => 'green', + 'count' => 0, + 'active' => false + ], + 2 => [ + 'label' => null, + 'value' => 'red', + 'count' => 0, + 'active' => false + ], + 3 => [ + 'label' => null, + 'value' => 'white', + 'count' => 3, + 'active' => true + ] + ], + 'range' => [] + ] + ], + 2 => [ + 'code' => 'size', + 'label' => null, + 'type' => 'list', + 'items' => [ + 'list' => [ + 0 => [ + "label" => null, + "value" => "43", + "count" => 0, + "active" => false + ], + 1 => [ + "label" => null, + "value" => "46", + "count" => 0, + "active" => false + ], + 2 => [ + "label" => null, + "value" => "47", + "count" => 0, + "active" => false + ], + 3 => [ + "label" => null, + "value" => "xl", + "count" => 2, + "active" => true + ], + 4 => [ + "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' => 100.0, + 'max' => 107.0 + ], + 'activeRange' => [ + 'min' => 105.0, + 'max' => 107.0 + ] + ] + ] + ], + ], + 4 => [ + 'code' => 'new', + 'label' => null, + 'type' => 'list', + 'items' => [ + 'list' => [ + 0 => [ + 'label' => null, + 'value' => "0", + 'count' => 1, + 'active' => true + ], + 1 => [ + 'label' => null, + 'value' => "1", + 'count' => 2, + 'active' => true + ] + ], + 'range' => [] + ] + ], + 5 => [ + 'code' => 'rating', + 'label' => null, + 'type' => 'list', + 'items' => [ + 'list' => [ + 0 => [ + 'label' => null, + 'value' => "3", + 'count' => 3, + 'active' => true + ], + ], + 'range' => [] + ] + ], + ] + ]; + + $this->assertEqualsCanonicalizing($expected, FormatData::formatDataWFacets($result)); + } + +} diff --git a/tests/Filter/IndexesTest.php b/tests/Filter/IndexesTest.php index 9745f9e..24af024 100644 --- a/tests/Filter/IndexesTest.php +++ b/tests/Filter/IndexesTest.php @@ -69,7 +69,7 @@ class IndexesTest extends AbstractTestCase ] ]); $esResponseToResult = new EsResponseToResult(); - $result = $esResponseToResult->fromResponse($response); + $result = $esResponseToResult->fromResponse($response, $this->configuration); unset($updateData['type']); $expected = [ @@ -80,4 +80,4 @@ class IndexesTest extends AbstractTestCase $this->assertEqualsCanonicalizing($expected, FormatData::formatDataProducts($result)); } -} \ No newline at end of file +} diff --git a/tests/Filter/QueryTest.php b/tests/Filter/QueryTest.php index 9c903aa..9770223 100644 --- a/tests/Filter/QueryTest.php +++ b/tests/Filter/QueryTest.php @@ -490,4 +490,147 @@ class QueryTest extends AbstractTestCase $this->assertEqualsCanonicalizing($expected, FormatData::formatDataWFacets($result)); } -} \ No newline at end of file + + public function testGlobalFilterMinPrice() + { + $filter = [ + 'price' => [ + 'key' => 'price', + 'lower' => 103, + ] + ]; + + $criteria = new Criteria(); + + + $filterCollectionQueryPrice = new FilterGroupCollection([ + new Filter( + new Field($filter['price']['key']), + FilterOperator::GTE, + new FilterNumber($filter['price']['lower']) + ), + ]); + $filterCollectionQueryPrice->setFilterType(FilterType::QUERY); + $criteria->getFilters()->add($filterCollectionQueryPrice); + + $q = new SearchQuery($criteria); + + $handler = SearchClient::getInstance(); + $result = $handler->handle($q)->result; + + $expected = [ + 'hits' => [ + 's4', + 'h1', + 'h2', + 'h3', + 'p1', + ], + "facets" => [ + 0 => [ + "code" => "brand", + "label" => null, + "type" => "list", + "items" => [ + "list" => [ + 0 => [ + "label" => null, + "value" => "nike", + "count" => 3, + "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" => 1, + "active" => true, + ], + 1 => [ + "label" => null, + "value" => "red", + "count" => 1, + "active" => true, + ], + 2 => [ + "label" => null, + "value" => "white", + "count" => 3, + "active" => true, + ], + ], + "range" => [], + ], + ], + 2 => [ + "code" => "size", + "label" => null, + "type" => "list", + "items" => [ + "list" => [ + 0 => [ + "label" => null, + "count" => 1, + "value" => "43", + "active" => true, + ], + 1 => [ + "label" => null, + "value" => "xl", + "count" => 3, + "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" => 5, + "active" => true, + "fullRange" => [ + "min" => 103.0, + "max" => 107.0, + ], + "activeRange" => [ + "min" => 103.0, + "max" => 107.0, + ] + ] + ] + ] + ] + ] + ]; + + $this->assertEqualsCanonicalizing($expected, FormatData::formatDataWFacets($result)); + } +} diff --git a/tests/Helpers/TestIndexProvider.php b/tests/Helpers/TestIndexProvider.php index 070d24c..3efdfd7 100644 --- a/tests/Helpers/TestIndexProvider.php +++ b/tests/Helpers/TestIndexProvider.php @@ -61,6 +61,9 @@ class TestIndexProvider implements IndexProvider } } + $document->setByConfiguration($this->configuration, 'new', $product['new']); + $document->setByConfiguration($this->configuration, 'rating', $product['rating']); + $product['type'] = $product['type'] ?? null; switch ($product['type']) { case 'update': @@ -119,4 +122,4 @@ class TestIndexProvider implements IndexProvider { return null; } -} \ No newline at end of file +} diff --git a/tests/Seed/DefaultSeed.php b/tests/Seed/DefaultSeed.php index cb867ed..b31cf9d 100644 --- a/tests/Seed/DefaultSeed.php +++ b/tests/Seed/DefaultSeed.php @@ -35,6 +35,8 @@ class DefaultSeed 'category' => 'shoes', 'properties' => ['brand' => 'adidas', 'color' => 'green', 'size' => 46,'price' => 100], 'year' => 2014, + 'new' => false, + 'rating' => 3, ], [ 'id' => 's2', @@ -42,6 +44,8 @@ class DefaultSeed 'category' => 'shoes', 'properties' => ['brand' => 'adidas', 'color' => 'red', 'size' => 47,'price' => 101], 'year' => 2023, + 'new' => true, + 'rating' => 3, ], [ 'id' => 's3', @@ -49,6 +53,8 @@ class DefaultSeed 'category' => 'shoes', 'properties' => ['brand' => 'rebook', 'color' => 'blue', 'size' => 47,'price' => 102], 'year' => 1980, + 'new' => false, + 'rating' => 3, ], [ 'id' => 's4', @@ -56,6 +62,8 @@ class DefaultSeed 'category' => 'shoes', 'properties' => ['brand' => 'nike', 'color' => 'green', 'size' => 43,'price' => 103], 'year' => 2014, + 'new' => true, + 'rating' => 5, ], [ 'id' => 'h1', @@ -63,6 +71,8 @@ class DefaultSeed 'category' => 't-short', 'properties' => ['brand' => 'nike', 'color' => 'red', 'size' => 'xl','price' => 104], 'year' => 2010, + 'new' => true, + 'rating' => 4, ], [ 'id' => 'h2', @@ -70,6 +80,8 @@ class DefaultSeed 'category' => 't-short', 'properties' => ['brand' => 'nike', 'color' => 'white', 'size' => 'xxl','price' => 105], 'year' => 2000, + 'new' => true, + 'rating' => 3, ], [ 'id' => 'h3', @@ -77,6 +89,8 @@ class DefaultSeed 'category' => 't-short', 'properties' => ['brand' => 'rebook', 'color' => 'white', 'size' => 'xl','price' => 106], 'year' => 1990, + 'new' => true, + 'rating' => 3, ], [ 'id' => 'p1', @@ -84,9 +98,11 @@ class DefaultSeed 'category' => 'prices', 'properties' => ['brand' => 'rebook', 'color' => 'white', 'size' => 'xl','price' => 107], 'year' => 2015, + 'new' => false, + 'rating' => 3, ], ]); $this->indexRunner->run($provider); } -} \ No newline at end of file +} -- GitLab