From f92be34481e14949b4a193605298434b2c53b2b3 Mon Sep 17 00:00:00 2001 From: "diogo.correia" Date: Wed, 10 Jul 2024 12:05:14 +0100 Subject: [PATCH 01/10] Added Implementation for Composite Aggregations. --- composer.json | 8 ++ .../Builder/CompositeAggregationBuilder.php | 109 ++++++++++++++++++ src/Query/Aggregation/SourceProperty.php | 15 +++ src/Query/Aggregation/Sources.php | 37 ++++++ src/Query/Criteria/Filters.php | 37 ++++++ .../CompositeAggregationRepository.php | 40 +++++++ ...ompositeAggregationRepositoryInterface.php | 13 +++ src/Result/CompositeResult.php | 15 +++ .../CompositeAggregationBuilderTest.php | 62 ++++++++++ 9 files changed, 336 insertions(+) create mode 100644 src/Query/Aggregation/Builder/CompositeAggregationBuilder.php create mode 100644 src/Query/Aggregation/SourceProperty.php create mode 100644 src/Query/Aggregation/Sources.php create mode 100644 src/Query/Criteria/Filters.php create mode 100644 src/Repository/CompositeAggregationRepository.php create mode 100644 src/Repository/CompositeAggregationRepositoryInterface.php create mode 100644 src/Result/CompositeResult.php create mode 100644 tests/Query/Aggregation/Builder/CompositeAggregationBuilderTest.php diff --git a/composer.json b/composer.json index f4e8b8a..40dc60f 100644 --- a/composer.json +++ b/composer.json @@ -4,6 +4,13 @@ "type": "library", "license": "proprietary", "minimum-stability": "stable", + "repositories": [ + { + "type": "vcs", + "url": "https://github.com/kununu/utilities.git", + "no-api": true + } + ], "require": { "php": ">=8.1", "ext-ctype": "*", @@ -11,6 +18,7 @@ "ext-json": "*", "ext-mbstring": "*", "elasticsearch/elasticsearch": "^7.0", + "kununu/utilities": "^4.8.0", "psr/log": "^1.0|^2.0|^3.0" }, "require-dev": { diff --git a/src/Query/Aggregation/Builder/CompositeAggregationBuilder.php b/src/Query/Aggregation/Builder/CompositeAggregationBuilder.php new file mode 100644 index 0000000..f847f1b --- /dev/null +++ b/src/Query/Aggregation/Builder/CompositeAggregationBuilder.php @@ -0,0 +1,109 @@ +afterKey = null; + $this->filters = new Filters(); + $this->name = null; + $this->sources = null; + } + + public static function create(): self + { + return new self(); + } + + public function withAfterKey(?array $afterKey): self + { + $this->afterKey = $afterKey; + + return $this; + } + + public function withFilters(Filters $filters): self + { + $this->filters = $filters; + + return $this; + } + + public function withName(string $name): self + { + $this->name = $name; + + return $this; + } + + public function withSources(Sources $sources): self + { + $this->sources = $sources; + + return $this; + } + + public function getName(): string + { + if (null === $this->name) { + throw new RuntimeException('Aggregation name is required'); + } + + return $this->name; + } + + public function getQuery(int $compositeSize = 100): QueryInterface + { + return RawQuery::create( + ArrayUtilities::filterNullAndEmptyValues([ + Q::query() => [ + Q::bool() => [ + Q::must() => $this->filters->map(fn(Filter $filter) => $filter->toArray()), + ], + ], + Q::aggs() => [ + $this->getName() => [ + Q::composite() => [ + Q::size() => $compositeSize, + Q::sources() => $this->sources?->map( + fn(SourceProperty $sourceProperty) => [ + $sourceProperty->source => [ + Q::terms() => [ + Q::field() => $sourceProperty->property, + Q::missingBucket() => $sourceProperty->missingBucket, + ] + ], + ] + ) ?? [], + Q::after() => $this->afterKey, + ], + ], + ], + ], true) + ); + } + + public function toArray(): array + { + return $this->getQuery()->toArray(); + } +} diff --git a/src/Query/Aggregation/SourceProperty.php b/src/Query/Aggregation/SourceProperty.php new file mode 100644 index 0000000..e258278 --- /dev/null +++ b/src/Query/Aggregation/SourceProperty.php @@ -0,0 +1,15 @@ +append($sourceProperty); + } + } + + public function current(): ?SourceProperty + { + $current = parent::current(); + assert($this->count() > 0 ? $current instanceof SourceProperty : null === $current); + + return $current; + } + + public function append($value): void + { + match (true) { + $value instanceof SourceProperty => parent::append($value), + default => throw new InvalidArgumentException(sprintf(self::INVALID, SourceProperty::class)) + }; + } +} diff --git a/src/Query/Criteria/Filters.php b/src/Query/Criteria/Filters.php new file mode 100644 index 0000000..c904913 --- /dev/null +++ b/src/Query/Criteria/Filters.php @@ -0,0 +1,37 @@ +append($propertyFilter); + } + } + + public function current(): ?Filter + { + $current = parent::current(); + assert($this->count() > 0 ? $current instanceof Filter : null === $current); + + return $current; + } + + public function append($value): void + { + match (true) { + $value instanceof Filter => parent::append($value), + default => throw new InvalidArgumentException(sprintf(self::INVALID, Filter::class)) + }; + } +} diff --git a/src/Repository/CompositeAggregationRepository.php b/src/Repository/CompositeAggregationRepository.php new file mode 100644 index 0000000..e3f3a8e --- /dev/null +++ b/src/Repository/CompositeAggregationRepository.php @@ -0,0 +1,40 @@ +withName($aggregationName) + ->withFilters($filters) + ->withSources($sources); + + do { + $result = $this->aggregateByQuery( + $elasticsearchQuery->getQuery()->limit(0) + )->getResultByName($aggregationName); + + foreach ($result?->getFields()[Q::buckets()] ?? [] as $bucket) { + if (!empty($bucket[Q::key()]) && !empty($bucket[Q::docCount()])) { + yield new CompositeResult( + $bucket[Q::key()], + $bucket[Q::docCount()], + $aggregationName + ); + } + } + + $elasticsearchQuery->withAfterKey($afterKey = ($result?->get(Q::afterKey()) ?? null)); + } while (null !== $afterKey); + } +} diff --git a/src/Repository/CompositeAggregationRepositoryInterface.php b/src/Repository/CompositeAggregationRepositoryInterface.php new file mode 100644 index 0000000..85bc6fc --- /dev/null +++ b/src/Repository/CompositeAggregationRepositoryInterface.php @@ -0,0 +1,13 @@ +withName('agg') + ->withFilters(new Filters( + new Filter('field', 'value') + )) + ->withSources( + new Sources( + new SourceProperty('field', 'value') + ) + ); + + self::assertEquals( + [ + 'query' => [ + 'bool' => [ + 'must' => [ + [ + 'term' => [ + 'field' => 'value' + ] + ] + ] + ] + ], + 'aggs' => [ + 'agg' => [ + 'composite' => [ + 'size' => 100, + 'sources' => [ + [ + 'field' => [ + 'terms' => [ + 'field' => 'value', + 'missing_bucket' => false, + ] + ] + ] + ] + ] + ] + ], + ], + $compositeAggregation->getQuery()->toArray() + ); + } +} \ No newline at end of file From aa364036e4a1525e5a9058d566fc6d2472f0d415 Mon Sep 17 00:00:00 2001 From: "diogo.correia" Date: Wed, 10 Jul 2024 16:47:55 +0100 Subject: [PATCH 02/10] Added Unit Tests. --- ...ompositeAggregationRepositoryInterface.php | 2 +- .../CompositeAggregationBuilderTest.php | 13 ++- .../Query/Aggregation/SourcePropertyTest.php | 19 ++++ tests/Query/Aggregation/SourcesTest.php | 21 +++++ tests/Query/Criteria/FiltersTest.php | 21 +++++ .../CompositeAggregationRepositoryTest.php | 87 +++++++++++++++++++ 6 files changed, 160 insertions(+), 3 deletions(-) create mode 100644 tests/Query/Aggregation/SourcePropertyTest.php create mode 100644 tests/Query/Aggregation/SourcesTest.php create mode 100644 tests/Query/Criteria/FiltersTest.php create mode 100644 tests/Repository/CompositeAggregationRepositoryTest.php diff --git a/src/Repository/CompositeAggregationRepositoryInterface.php b/src/Repository/CompositeAggregationRepositoryInterface.php index 85bc6fc..504afb3 100644 --- a/src/Repository/CompositeAggregationRepositoryInterface.php +++ b/src/Repository/CompositeAggregationRepositoryInterface.php @@ -10,4 +10,4 @@ interface CompositeAggregationRepositoryInterface { public function lookup(Filters $filters, Sources $sources, string $aggregationName): Generator; -} \ No newline at end of file +} diff --git a/tests/Query/Aggregation/Builder/CompositeAggregationBuilderTest.php b/tests/Query/Aggregation/Builder/CompositeAggregationBuilderTest.php index 12a178b..7e753ed 100644 --- a/tests/Query/Aggregation/Builder/CompositeAggregationBuilderTest.php +++ b/tests/Query/Aggregation/Builder/CompositeAggregationBuilderTest.php @@ -8,6 +8,7 @@ use Kununu\Elasticsearch\Query\Aggregation\Sources; use Kununu\Elasticsearch\Query\Criteria\Filter; use Kununu\Elasticsearch\Query\Criteria\Filters; +use Kununu\Elasticsearch\Query\Criteria\Operator; use PHPUnit\Framework\TestCase; class CompositeAggregationBuilderTest extends TestCase @@ -17,7 +18,8 @@ public function testCompositeAggregationBuilder(): void $compositeAggregation = CompositeAggregationBuilder::create() ->withName('agg') ->withFilters(new Filters( - new Filter('field', 'value') + new Filter('field', 'value'), + new Filter('field2', 'value2', Operator::GREATER_THAN_EQUALS) )) ->withSources( new Sources( @@ -34,6 +36,13 @@ public function testCompositeAggregationBuilder(): void 'term' => [ 'field' => 'value' ] + ], + [ + 'range' => [ + 'field2' => [ + 'gte' => 'value2' + ] + ] ] ] ] @@ -59,4 +68,4 @@ public function testCompositeAggregationBuilder(): void $compositeAggregation->getQuery()->toArray() ); } -} \ No newline at end of file +} diff --git a/tests/Query/Aggregation/SourcePropertyTest.php b/tests/Query/Aggregation/SourcePropertyTest.php new file mode 100644 index 0000000..f32e157 --- /dev/null +++ b/tests/Query/Aggregation/SourcePropertyTest.php @@ -0,0 +1,19 @@ +source); + self::assertEquals('property', $sourceProperty->property); + self::assertTrue($sourceProperty->missingBucket); + } +} \ No newline at end of file diff --git a/tests/Query/Aggregation/SourcesTest.php b/tests/Query/Aggregation/SourcesTest.php new file mode 100644 index 0000000..0e6c301 --- /dev/null +++ b/tests/Query/Aggregation/SourcesTest.php @@ -0,0 +1,21 @@ +append(new SourceProperty('source2', 'property2', false)); + self::assertCount(2, $sources); + } +} diff --git a/tests/Query/Criteria/FiltersTest.php b/tests/Query/Criteria/FiltersTest.php new file mode 100644 index 0000000..175cb9a --- /dev/null +++ b/tests/Query/Criteria/FiltersTest.php @@ -0,0 +1,21 @@ +append(new Filter('field2', 'value2')); + self::assertCount(2, $filters); + } +} diff --git a/tests/Repository/CompositeAggregationRepositoryTest.php b/tests/Repository/CompositeAggregationRepositoryTest.php new file mode 100644 index 0000000..3e962a7 --- /dev/null +++ b/tests/Repository/CompositeAggregationRepositoryTest.php @@ -0,0 +1,87 @@ +client + ->expects($this->once()) + ->method('search') + ->with( + [ + 'index' => 'index_read', + 'body' => [ + 'size' => 0, + 'aggs' => [ + 'agg' => [ + 'composite' => [ + 'size' => 100, + 'sources' => [ + ['source' => ['terms' => ['field' => 'property', 'missing_bucket' => false]]], + ], + ], + ], + ], + ] + ] + ) + ->willReturn([ + 'aggregations' => [ + 'agg' => [ + 'buckets' => [ + ['key' => ['source' => 'value1'], 'doc_count' => 1], + ['key' => ['source' => 'value2'], 'doc_count' => 30], + ], + ], + ], + ]); + + $generator = $this->repository->lookup( + new Filters(), + new Sources(new SourceProperty('source', 'property')), + 'agg' + ); + + $items = []; + foreach ($generator as $item) { + $items[] = $item; + } + + self::assertCount(2, $items); + self::assertEquals([ + new CompositeResult(['source' => 'value1'], 1, 'agg'), + new CompositeResult(['source' => 'value2'], 30, 'agg') + ], $items); + } + + protected function setUp(): void + { + parent::setUp(); + + $this->client = $this->createMock(Client::class); + $this->repository = new CompositeAggregationRepository( + $this->client, + [ + 'index_read' => 'index_read', + 'index_write' => 'index_write', + 'type' => '_doc', + ] + ); + } +} From 5e9a3998c6aa20a8e3431f80753789bf0218db16 Mon Sep 17 00:00:00 2001 From: "diogo.correia" Date: Thu, 11 Jul 2024 11:30:41 +0100 Subject: [PATCH 03/10] Required kununu/collections package and created ArrayUtilities with filterNullAndEmptyValues method. --- composer.json | 9 +- .../Builder/CompositeAggregationBuilder.php | 25 +++-- .../CompositeAggregationRepository.php | 11 +-- src/Util/ArrayUtilities.php | 20 ++++ .../Query/Aggregation/SourcePropertyTest.php | 2 +- tests/Util/ArrayUtilitiesTest.php | 95 +++++++++++++++++++ 6 files changed, 134 insertions(+), 28 deletions(-) create mode 100644 src/Util/ArrayUtilities.php create mode 100644 tests/Util/ArrayUtilitiesTest.php diff --git a/composer.json b/composer.json index 40dc60f..f1be55a 100644 --- a/composer.json +++ b/composer.json @@ -4,13 +4,6 @@ "type": "library", "license": "proprietary", "minimum-stability": "stable", - "repositories": [ - { - "type": "vcs", - "url": "https://github.com/kununu/utilities.git", - "no-api": true - } - ], "require": { "php": ">=8.1", "ext-ctype": "*", @@ -18,7 +11,7 @@ "ext-json": "*", "ext-mbstring": "*", "elasticsearch/elasticsearch": "^7.0", - "kununu/utilities": "^4.8.0", + "kununu/collections": "^4.1.0", "psr/log": "^1.0|^2.0|^3.0" }, "require-dev": { diff --git a/src/Query/Aggregation/Builder/CompositeAggregationBuilder.php b/src/Query/Aggregation/Builder/CompositeAggregationBuilder.php index f847f1b..12bae84 100644 --- a/src/Query/Aggregation/Builder/CompositeAggregationBuilder.php +++ b/src/Query/Aggregation/Builder/CompositeAggregationBuilder.php @@ -10,8 +10,7 @@ use Kununu\Elasticsearch\Query\Criteria\Filters; use Kununu\Elasticsearch\Query\QueryInterface; use Kununu\Elasticsearch\Query\RawQuery; -use Kununu\Utilities\Arrays\ArrayUtilities; -use Kununu\Utilities\Elasticsearch\Q; +use Kununu\Elasticsearch\Util\ArrayUtilities; use RuntimeException; class CompositeAggregationBuilder implements AggregationInterface @@ -75,26 +74,26 @@ public function getQuery(int $compositeSize = 100): QueryInterface { return RawQuery::create( ArrayUtilities::filterNullAndEmptyValues([ - Q::query() => [ - Q::bool() => [ - Q::must() => $this->filters->map(fn(Filter $filter) => $filter->toArray()), + 'query' => [ + 'bool' => [ + 'must' => $this->filters->map(fn(Filter $filter) => $filter->toArray()), ], ], - Q::aggs() => [ + 'aggs' => [ $this->getName() => [ - Q::composite() => [ - Q::size() => $compositeSize, - Q::sources() => $this->sources?->map( + 'composite' => [ + 'size' => $compositeSize, + 'sources' => $this->sources?->map( fn(SourceProperty $sourceProperty) => [ $sourceProperty->source => [ - Q::terms() => [ - Q::field() => $sourceProperty->property, - Q::missingBucket() => $sourceProperty->missingBucket, + 'terms' => [ + 'field' => $sourceProperty->property, + 'missing_bucket' => $sourceProperty->missingBucket, ] ], ] ) ?? [], - Q::after() => $this->afterKey, + 'after' => $this->afterKey, ], ], ], diff --git a/src/Repository/CompositeAggregationRepository.php b/src/Repository/CompositeAggregationRepository.php index e3f3a8e..e8c8da8 100644 --- a/src/Repository/CompositeAggregationRepository.php +++ b/src/Repository/CompositeAggregationRepository.php @@ -8,7 +8,6 @@ use Kununu\Elasticsearch\Query\Aggregation\Sources; use Kununu\Elasticsearch\Query\Criteria\Filters; use Kununu\Elasticsearch\Result\CompositeResult; -use Kununu\Utilities\Elasticsearch\Q; final class CompositeAggregationRepository extends Repository implements CompositeAggregationRepositoryInterface { @@ -24,17 +23,17 @@ public function lookup(Filters $filters, Sources $sources, string $aggregationNa $elasticsearchQuery->getQuery()->limit(0) )->getResultByName($aggregationName); - foreach ($result?->getFields()[Q::buckets()] ?? [] as $bucket) { - if (!empty($bucket[Q::key()]) && !empty($bucket[Q::docCount()])) { + foreach ($result?->getFields()['buckets'] ?? [] as $bucket) { + if (!empty($bucket['key']) && !empty($bucket['doc_count'])) { yield new CompositeResult( - $bucket[Q::key()], - $bucket[Q::docCount()], + $bucket['key'], + $bucket['doc_count'], $aggregationName ); } } - $elasticsearchQuery->withAfterKey($afterKey = ($result?->get(Q::afterKey()) ?? null)); + $elasticsearchQuery->withAfterKey($afterKey = ($result?->get('after_key') ?? null)); } while (null !== $afterKey); } } diff --git a/src/Util/ArrayUtilities.php b/src/Util/ArrayUtilities.php new file mode 100644 index 0000000..cdd65e7 --- /dev/null +++ b/src/Util/ArrayUtilities.php @@ -0,0 +1,20 @@ + $value !== null && $value !== []); + } +} diff --git a/tests/Query/Aggregation/SourcePropertyTest.php b/tests/Query/Aggregation/SourcePropertyTest.php index f32e157..697d75e 100644 --- a/tests/Query/Aggregation/SourcePropertyTest.php +++ b/tests/Query/Aggregation/SourcePropertyTest.php @@ -16,4 +16,4 @@ public function testSourceProperty(): void self::assertEquals('property', $sourceProperty->property); self::assertTrue($sourceProperty->missingBucket); } -} \ No newline at end of file +} diff --git a/tests/Util/ArrayUtilitiesTest.php b/tests/Util/ArrayUtilitiesTest.php new file mode 100644 index 0000000..63120f1 --- /dev/null +++ b/tests/Util/ArrayUtilitiesTest.php @@ -0,0 +1,95 @@ + [ + [ + 'a' => 1, + 'b' => [ + 'c' => null, + 'd' => [ + 'e' => null, + 'f' => 4, + 'g' => [ + 'i' => null, + 'j' => false, + 'k' => 0, + 'l' => '' + ], + ], + ], + 'h' => null, + 'i' => [], + 'j' => '', + ], + false, + [ + 'a' => 1, + 'b' => [ + 'c' => null, + 'd' => [ + 'e' => null, + 'f' => 4, + 'g' => [ + 'i' => null, + 'j' => false, + 'k' => 0, + 'l' => '' + ], + ], + ], + 'j' => '', + ], + ], + 'recursive' => [ + [ + 'a' => 1, + 'b' => [ + 'c' => null, + 'd' => [ + 'e' => null, + 'f' => 4, + 'g' => [ + 'i' => null, + 'j' => false, + 'k' => 0, + 'l' => '' + ], + ], + ], + 'h' => null, + ], + true, + [ + 'a' => 1, + 'b' => [ + 'd' => [ + 'f' => 4, + 'g' => [ + 'j' => false, + 'k' => 0, + 'l' => '' + ] + ], + ], + ], + ], + ]; + } +} From edf66a24886a0e9929502c18730b9c05fb7f1eb4 Mon Sep 17 00:00:00 2001 From: "diogo.correia" Date: Thu, 11 Jul 2024 11:52:33 +0100 Subject: [PATCH 04/10] Added code coverage. --- .../Builder/CompositeAggregationBuilderTest.php | 6 +++++- tests/Query/Aggregation/SourcesTest.php | 9 +++++++++ tests/Query/Criteria/FiltersTest.php | 9 +++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/tests/Query/Aggregation/Builder/CompositeAggregationBuilderTest.php b/tests/Query/Aggregation/Builder/CompositeAggregationBuilderTest.php index 7e753ed..306de8a 100644 --- a/tests/Query/Aggregation/Builder/CompositeAggregationBuilderTest.php +++ b/tests/Query/Aggregation/Builder/CompositeAggregationBuilderTest.php @@ -9,6 +9,7 @@ use Kununu\Elasticsearch\Query\Criteria\Filter; use Kununu\Elasticsearch\Query\Criteria\Filters; use Kununu\Elasticsearch\Query\Criteria\Operator; +use Kununu\Elasticsearch\Query\RawQuery; use PHPUnit\Framework\TestCase; class CompositeAggregationBuilderTest extends TestCase @@ -27,6 +28,9 @@ public function testCompositeAggregationBuilder(): void ) ); + $query = $compositeAggregation->getQuery(); + self::assertInstanceOf(RawQuery::class, $query); + self::assertEquals( [ 'query' => [ @@ -65,7 +69,7 @@ public function testCompositeAggregationBuilder(): void ] ], ], - $compositeAggregation->getQuery()->toArray() + $compositeAggregation->toArray() ); } } diff --git a/tests/Query/Aggregation/SourcesTest.php b/tests/Query/Aggregation/SourcesTest.php index 0e6c301..7fbf369 100644 --- a/tests/Query/Aggregation/SourcesTest.php +++ b/tests/Query/Aggregation/SourcesTest.php @@ -3,6 +3,7 @@ namespace Kununu\Elasticsearch\Tests\Query\Aggregation; +use InvalidArgumentException; use Kununu\Elasticsearch\Query\Aggregation\SourceProperty; use Kununu\Elasticsearch\Query\Aggregation\Sources; use PHPUnit\Framework\TestCase; @@ -18,4 +19,12 @@ public function testSources(): void $sources->append(new SourceProperty('source2', 'property2', false)); self::assertCount(2, $sources); } + + public function testSourcesWithInvalidSourceProperty(): void + { + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage('Can only append Kununu\Elasticsearch\Query\Aggregation\SourceProperty'); + + (new Sources())->append('invalid'); + } } diff --git a/tests/Query/Criteria/FiltersTest.php b/tests/Query/Criteria/FiltersTest.php index 175cb9a..37c653a 100644 --- a/tests/Query/Criteria/FiltersTest.php +++ b/tests/Query/Criteria/FiltersTest.php @@ -3,6 +3,7 @@ namespace Kununu\Elasticsearch\Tests\Query\Criteria; +use InvalidArgumentException; use Kununu\Elasticsearch\Query\Criteria\Filter; use Kununu\Elasticsearch\Query\Criteria\Filters; use PHPUnit\Framework\TestCase; @@ -18,4 +19,12 @@ public function testFilters(): void $filters->append(new Filter('field2', 'value2')); self::assertCount(2, $filters); } + + public function testFiltersWithInvalidFilter(): void + { + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage('Can only append Kununu\Elasticsearch\Query\Criteria\Filter'); + + (new Filters())->append('invalid'); + } } From f8919067781ee26b1bad186b9a2e17d0ae791c84 Mon Sep 17 00:00:00 2001 From: "diogo.correia" Date: Thu, 11 Jul 2024 12:15:02 +0100 Subject: [PATCH 05/10] Added code coverage. --- .../MissingAggregationAttributesException.php | 10 +++ .../Builder/CompositeAggregationBuilder.php | 3 +- .../CompositeAggregationBuilderTest.php | 64 +++++++++++++++++++ tests/Query/Aggregation/SourcesTest.php | 4 +- tests/Query/Criteria/FiltersTest.php | 4 +- 5 files changed, 80 insertions(+), 5 deletions(-) create mode 100644 src/Exception/MissingAggregationAttributesException.php diff --git a/src/Exception/MissingAggregationAttributesException.php b/src/Exception/MissingAggregationAttributesException.php new file mode 100644 index 0000000..d053907 --- /dev/null +++ b/src/Exception/MissingAggregationAttributesException.php @@ -0,0 +1,10 @@ +name) { - throw new RuntimeException('Aggregation name is required'); + throw new MissingAggregationAttributesException('Aggregation name is missing'); } return $this->name; diff --git a/tests/Query/Aggregation/Builder/CompositeAggregationBuilderTest.php b/tests/Query/Aggregation/Builder/CompositeAggregationBuilderTest.php index 306de8a..cabbb13 100644 --- a/tests/Query/Aggregation/Builder/CompositeAggregationBuilderTest.php +++ b/tests/Query/Aggregation/Builder/CompositeAggregationBuilderTest.php @@ -3,6 +3,7 @@ namespace Kununu\Elasticsearch\Tests\Query\Aggregation\Builder; +use Kununu\Elasticsearch\Exception\MissingAggregationAttributesException; use Kununu\Elasticsearch\Query\Aggregation\Builder\CompositeAggregationBuilder; use Kununu\Elasticsearch\Query\Aggregation\SourceProperty; use Kununu\Elasticsearch\Query\Aggregation\Sources; @@ -71,5 +72,68 @@ public function testCompositeAggregationBuilder(): void ], $compositeAggregation->toArray() ); + + $compositeAggregation->withAfterKey(['field' => 'value']); + + self::assertEquals( + [ + 'query' => [ + 'bool' => [ + 'must' => [ + [ + 'term' => [ + 'field' => 'value' + ] + ], + [ + 'range' => [ + 'field2' => [ + 'gte' => 'value2' + ] + ] + ] + ] + ] + ], + 'aggs' => [ + 'agg' => [ + 'composite' => [ + 'size' => 100, + 'sources' => [ + [ + 'field' => [ + 'terms' => [ + 'field' => 'value', + 'missing_bucket' => false, + ] + ] + ] + ], + 'after' => ['field' => 'value'] + ] + ] + ], + ], + $compositeAggregation->toArray() + ); + } + + public function testCompositeAggregationBuilderWithNoAggregationName() + { + self::expectException(MissingAggregationAttributesException::class); + self::expectExceptionMessage('Aggregation name is missing'); + + $compositeAggregation = CompositeAggregationBuilder::create() + ->withFilters(new Filters( + new Filter('field', 'value'), + new Filter('field2', 'value2', Operator::GREATER_THAN_EQUALS) + )) + ->withSources( + new Sources( + new SourceProperty('field', 'value') + ) + ); + + $compositeAggregation->toArray(); } } diff --git a/tests/Query/Aggregation/SourcesTest.php b/tests/Query/Aggregation/SourcesTest.php index 7fbf369..bf2561f 100644 --- a/tests/Query/Aggregation/SourcesTest.php +++ b/tests/Query/Aggregation/SourcesTest.php @@ -22,8 +22,8 @@ public function testSources(): void public function testSourcesWithInvalidSourceProperty(): void { - $this->expectException(InvalidArgumentException::class); - $this->expectExceptionMessage('Can only append Kununu\Elasticsearch\Query\Aggregation\SourceProperty'); + self::expectException(InvalidArgumentException::class); + self::expectExceptionMessage('Can only append Kununu\Elasticsearch\Query\Aggregation\SourceProperty'); (new Sources())->append('invalid'); } diff --git a/tests/Query/Criteria/FiltersTest.php b/tests/Query/Criteria/FiltersTest.php index 37c653a..7d99d4e 100644 --- a/tests/Query/Criteria/FiltersTest.php +++ b/tests/Query/Criteria/FiltersTest.php @@ -22,8 +22,8 @@ public function testFilters(): void public function testFiltersWithInvalidFilter(): void { - $this->expectException(InvalidArgumentException::class); - $this->expectExceptionMessage('Can only append Kununu\Elasticsearch\Query\Criteria\Filter'); + self::expectException(InvalidArgumentException::class); + self::expectExceptionMessage('Can only append Kununu\Elasticsearch\Query\Criteria\Filter'); (new Filters())->append('invalid'); } From 16ca6dc2f04525845918f02a67ff8a20d1a78317 Mon Sep 17 00:00:00 2001 From: "diogo.correia" Date: Thu, 11 Jul 2024 14:03:54 +0100 Subject: [PATCH 06/10] Added Unit Test. --- .../MissingAggregationAttributesException.php | 2 +- tests/Result/CompositeResultTest.php | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 tests/Result/CompositeResultTest.php diff --git a/src/Exception/MissingAggregationAttributesException.php b/src/Exception/MissingAggregationAttributesException.php index d053907..83e2da0 100644 --- a/src/Exception/MissingAggregationAttributesException.php +++ b/src/Exception/MissingAggregationAttributesException.php @@ -7,4 +7,4 @@ class MissingAggregationAttributesException extends RuntimeException { -} \ No newline at end of file +} diff --git a/tests/Result/CompositeResultTest.php b/tests/Result/CompositeResultTest.php new file mode 100644 index 0000000..2923113 --- /dev/null +++ b/tests/Result/CompositeResultTest.php @@ -0,0 +1,19 @@ + 'value'], 1, 'agg'); + + self::assertEquals(['key' => 'value'], $compositeResult->results); + self::assertEquals(1, $compositeResult->documentsCount); + self::assertEquals('agg', $compositeResult->aggregationName); + } +} \ No newline at end of file From 6f891522dca6173c089bfc68bb775f875ab278f7 Mon Sep 17 00:00:00 2001 From: "diogo.correia" Date: Fri, 12 Jul 2024 14:15:39 +0100 Subject: [PATCH 07/10] Applied some refactor changes into Repository. --- ...p => CompositeAggregationQueryBuilder.php} | 27 +++--- .../CompositeAggregationQueryInterface.php | 17 ++++ .../CompositeAggregationRepository.php | 39 -------- ...ompositeAggregationRepositoryInterface.php | 13 --- src/Repository/Repository.php | 27 ++++++ .../CompositeAggregationBuilderTest.php | 16 ++-- .../CompositeAggregationRepositoryTest.php | 87 ----------------- ...epositoryAggregateCompositeByQueryTest.php | 94 +++++++++++++++++++ 8 files changed, 159 insertions(+), 161 deletions(-) rename src/Query/Aggregation/Builder/{CompositeAggregationBuilder.php => CompositeAggregationQueryBuilder.php} (75%) create mode 100644 src/Query/CompositeAggregationQueryInterface.php delete mode 100644 src/Repository/CompositeAggregationRepository.php delete mode 100644 src/Repository/CompositeAggregationRepositoryInterface.php delete mode 100644 tests/Repository/CompositeAggregationRepositoryTest.php create mode 100644 tests/Repository/RepositoryAggregateCompositeByQueryTest.php diff --git a/src/Query/Aggregation/Builder/CompositeAggregationBuilder.php b/src/Query/Aggregation/Builder/CompositeAggregationQueryBuilder.php similarity index 75% rename from src/Query/Aggregation/Builder/CompositeAggregationBuilder.php rename to src/Query/Aggregation/Builder/CompositeAggregationQueryBuilder.php index dbb8f5f..4337c38 100644 --- a/src/Query/Aggregation/Builder/CompositeAggregationBuilder.php +++ b/src/Query/Aggregation/Builder/CompositeAggregationQueryBuilder.php @@ -6,15 +6,14 @@ use Kununu\Elasticsearch\Exception\MissingAggregationAttributesException; use Kununu\Elasticsearch\Query\Aggregation\SourceProperty; use Kununu\Elasticsearch\Query\Aggregation\Sources; -use Kununu\Elasticsearch\Query\AggregationInterface; +use Kununu\Elasticsearch\Query\CompositeAggregationQueryInterface; use Kununu\Elasticsearch\Query\Criteria\Filter; use Kununu\Elasticsearch\Query\Criteria\Filters; use Kununu\Elasticsearch\Query\QueryInterface; use Kununu\Elasticsearch\Query\RawQuery; use Kununu\Elasticsearch\Util\ArrayUtilities; -use RuntimeException; -class CompositeAggregationBuilder implements AggregationInterface +class CompositeAggregationQueryBuilder implements CompositeAggregationQueryInterface { private ?array $afterKey; private Filters $filters; @@ -62,7 +61,7 @@ public function withSources(Sources $sources): self return $this; } - public function getName(): string + public function name(): string { if (null === $this->name) { throw new MissingAggregationAttributesException('Aggregation name is missing'); @@ -81,19 +80,19 @@ public function getQuery(int $compositeSize = 100): QueryInterface ], ], 'aggs' => [ - $this->getName() => [ + $this->name() => [ 'composite' => [ 'size' => $compositeSize, 'sources' => $this->sources?->map( - fn(SourceProperty $sourceProperty) => [ - $sourceProperty->source => [ - 'terms' => [ - 'field' => $sourceProperty->property, - 'missing_bucket' => $sourceProperty->missingBucket, - ] - ], - ] - ) ?? [], + fn(SourceProperty $sourceProperty) => [ + $sourceProperty->source => [ + 'terms' => [ + 'field' => $sourceProperty->property, + 'missing_bucket' => $sourceProperty->missingBucket, + ] + ], + ] + ) ?? [], 'after' => $this->afterKey, ], ], diff --git a/src/Query/CompositeAggregationQueryInterface.php b/src/Query/CompositeAggregationQueryInterface.php new file mode 100644 index 0000000..29240ad --- /dev/null +++ b/src/Query/CompositeAggregationQueryInterface.php @@ -0,0 +1,17 @@ +withName($aggregationName) - ->withFilters($filters) - ->withSources($sources); - - do { - $result = $this->aggregateByQuery( - $elasticsearchQuery->getQuery()->limit(0) - )->getResultByName($aggregationName); - - foreach ($result?->getFields()['buckets'] ?? [] as $bucket) { - if (!empty($bucket['key']) && !empty($bucket['doc_count'])) { - yield new CompositeResult( - $bucket['key'], - $bucket['doc_count'], - $aggregationName - ); - } - } - - $elasticsearchQuery->withAfterKey($afterKey = ($result?->get('after_key') ?? null)); - } while (null !== $afterKey); - } -} diff --git a/src/Repository/CompositeAggregationRepositoryInterface.php b/src/Repository/CompositeAggregationRepositoryInterface.php deleted file mode 100644 index 504afb3..0000000 --- a/src/Repository/CompositeAggregationRepositoryInterface.php +++ /dev/null @@ -1,13 +0,0 @@ - */ + public function aggregateCompositeByQuery(CompositeAggregationQueryInterface $query): Generator + { + $afterKey = null; + + do { + $result = $this->aggregateByQuery( + $query->withAfterKey($afterKey)->getQuery() + )->getResultByName($query->name()); + + foreach ($result?->getFields()['buckets'] ?? [] as $bucket) { + if (!empty($bucket['key']) && !empty($bucket['doc_count'])) { + yield new CompositeResult( + $bucket['key'], + $bucket['doc_count'], + $query->name() + ); + } + } + + $afterKey = $result?->get('after_key') ?? null; + } while (null !== $afterKey); + } + public function updateByQuery(QueryInterface $query, array $updateScript): array { return $this->executeWrite( diff --git a/tests/Query/Aggregation/Builder/CompositeAggregationBuilderTest.php b/tests/Query/Aggregation/Builder/CompositeAggregationBuilderTest.php index cabbb13..9a9cc36 100644 --- a/tests/Query/Aggregation/Builder/CompositeAggregationBuilderTest.php +++ b/tests/Query/Aggregation/Builder/CompositeAggregationBuilderTest.php @@ -4,7 +4,7 @@ namespace Kununu\Elasticsearch\Tests\Query\Aggregation\Builder; use Kununu\Elasticsearch\Exception\MissingAggregationAttributesException; -use Kununu\Elasticsearch\Query\Aggregation\Builder\CompositeAggregationBuilder; +use Kununu\Elasticsearch\Query\Aggregation\Builder\CompositeAggregationQueryBuilder; use Kununu\Elasticsearch\Query\Aggregation\SourceProperty; use Kununu\Elasticsearch\Query\Aggregation\Sources; use Kununu\Elasticsearch\Query\Criteria\Filter; @@ -17,7 +17,7 @@ class CompositeAggregationBuilderTest extends TestCase { public function testCompositeAggregationBuilder(): void { - $compositeAggregation = CompositeAggregationBuilder::create() + $compositeAggregation = CompositeAggregationQueryBuilder::create() ->withName('agg') ->withFilters(new Filters( new Filter('field', 'value'), @@ -25,7 +25,7 @@ public function testCompositeAggregationBuilder(): void )) ->withSources( new Sources( - new SourceProperty('field', 'value') + new SourceProperty('source', 'property') ) ); @@ -58,9 +58,9 @@ public function testCompositeAggregationBuilder(): void 'size' => 100, 'sources' => [ [ - 'field' => [ + 'source' => [ 'terms' => [ - 'field' => 'value', + 'field' => 'property', 'missing_bucket' => false, ] ] @@ -101,9 +101,9 @@ public function testCompositeAggregationBuilder(): void 'size' => 100, 'sources' => [ [ - 'field' => [ + 'source' => [ 'terms' => [ - 'field' => 'value', + 'field' => 'property', 'missing_bucket' => false, ] ] @@ -123,7 +123,7 @@ public function testCompositeAggregationBuilderWithNoAggregationName() self::expectException(MissingAggregationAttributesException::class); self::expectExceptionMessage('Aggregation name is missing'); - $compositeAggregation = CompositeAggregationBuilder::create() + $compositeAggregation = CompositeAggregationQueryBuilder::create() ->withFilters(new Filters( new Filter('field', 'value'), new Filter('field2', 'value2', Operator::GREATER_THAN_EQUALS) diff --git a/tests/Repository/CompositeAggregationRepositoryTest.php b/tests/Repository/CompositeAggregationRepositoryTest.php deleted file mode 100644 index 3e962a7..0000000 --- a/tests/Repository/CompositeAggregationRepositoryTest.php +++ /dev/null @@ -1,87 +0,0 @@ -client - ->expects($this->once()) - ->method('search') - ->with( - [ - 'index' => 'index_read', - 'body' => [ - 'size' => 0, - 'aggs' => [ - 'agg' => [ - 'composite' => [ - 'size' => 100, - 'sources' => [ - ['source' => ['terms' => ['field' => 'property', 'missing_bucket' => false]]], - ], - ], - ], - ], - ] - ] - ) - ->willReturn([ - 'aggregations' => [ - 'agg' => [ - 'buckets' => [ - ['key' => ['source' => 'value1'], 'doc_count' => 1], - ['key' => ['source' => 'value2'], 'doc_count' => 30], - ], - ], - ], - ]); - - $generator = $this->repository->lookup( - new Filters(), - new Sources(new SourceProperty('source', 'property')), - 'agg' - ); - - $items = []; - foreach ($generator as $item) { - $items[] = $item; - } - - self::assertCount(2, $items); - self::assertEquals([ - new CompositeResult(['source' => 'value1'], 1, 'agg'), - new CompositeResult(['source' => 'value2'], 30, 'agg') - ], $items); - } - - protected function setUp(): void - { - parent::setUp(); - - $this->client = $this->createMock(Client::class); - $this->repository = new CompositeAggregationRepository( - $this->client, - [ - 'index_read' => 'index_read', - 'index_write' => 'index_write', - 'type' => '_doc', - ] - ); - } -} diff --git a/tests/Repository/RepositoryAggregateCompositeByQueryTest.php b/tests/Repository/RepositoryAggregateCompositeByQueryTest.php new file mode 100644 index 0000000..cf81784 --- /dev/null +++ b/tests/Repository/RepositoryAggregateCompositeByQueryTest.php @@ -0,0 +1,94 @@ +createMock(QueryInterface::class); + $compositeQuery = $this->createMock(CompositeAggregationQueryInterface::class); + + $query + ->expects($this->once()) + ->method('toArray') + ->willReturn( + [ + 'aggs' => [ + 'agg' => [ + 'composite' => [ + 'size' => 100, + 'sources' => [ + ['source' => ['terms' => ['field' => 'property', 'missing_bucket' => false]]], + ], + ], + ], + ] + ] + ); + + $compositeQuery + ->expects($this->any()) + ->method('name') + ->willReturn('agg'); + + $compositeQuery + ->expects($this->once()) + ->method('withAfterKey') + ->with(null) + ->willReturn($compositeQuery); + + $compositeQuery + ->expects($this->once()) + ->method('getQuery') + ->willReturn($query); + + $this->clientMock + ->expects($this->once()) + ->method('search') + ->with( + [ + 'index' => 'some_index_read', + 'body' => [ + #'size' => 0, + 'aggs' => [ + 'agg' => [ + 'composite' => [ + 'size' => 100, + 'sources' => [ + ['source' => ['terms' => ['field' => 'property', 'missing_bucket' => false]]], + ], + ], + ], + ], + ] + ] + ) + ->willReturn([ + 'aggregations' => [ + 'agg' => [ + 'buckets' => [ + ['key' => ['property' => 'value1'], 'doc_count' => 1], + ['key' => ['property' => 'value2'], 'doc_count' => 30], + ], + ], + ], + ]); + + $compositeResults = []; + foreach ($this->getRepository()->aggregateCompositeByQuery($compositeQuery) as $item) { + $compositeResults[] = $item; + } + + self::assertCount(2, $compositeResults); + self::assertEquals([ + new CompositeResult(['property' => 'value1'], 1, 'agg'), + new CompositeResult(['property' => 'value2'], 30, 'agg') + ], $compositeResults); + } +} From 7772cb3ea8d853b4d246e2545af80dfe2ce21515 Mon Sep 17 00:00:00 2001 From: "diogo.correia" Date: Fri, 12 Jul 2024 14:20:37 +0100 Subject: [PATCH 08/10] Applied some implementations as final. --- src/Exception/MissingAggregationAttributesException.php | 2 +- .../Aggregation/Builder/CompositeAggregationQueryBuilder.php | 2 +- .../Aggregation/Builder/CompositeAggregationBuilderTest.php | 2 +- tests/Result/CompositeResultTest.php | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Exception/MissingAggregationAttributesException.php b/src/Exception/MissingAggregationAttributesException.php index 83e2da0..37d80d5 100644 --- a/src/Exception/MissingAggregationAttributesException.php +++ b/src/Exception/MissingAggregationAttributesException.php @@ -5,6 +5,6 @@ use RuntimeException; -class MissingAggregationAttributesException extends RuntimeException +final class MissingAggregationAttributesException extends RuntimeException { } diff --git a/src/Query/Aggregation/Builder/CompositeAggregationQueryBuilder.php b/src/Query/Aggregation/Builder/CompositeAggregationQueryBuilder.php index 4337c38..06c3ea2 100644 --- a/src/Query/Aggregation/Builder/CompositeAggregationQueryBuilder.php +++ b/src/Query/Aggregation/Builder/CompositeAggregationQueryBuilder.php @@ -13,7 +13,7 @@ use Kununu\Elasticsearch\Query\RawQuery; use Kununu\Elasticsearch\Util\ArrayUtilities; -class CompositeAggregationQueryBuilder implements CompositeAggregationQueryInterface +final class CompositeAggregationQueryBuilder implements CompositeAggregationQueryInterface { private ?array $afterKey; private Filters $filters; diff --git a/tests/Query/Aggregation/Builder/CompositeAggregationBuilderTest.php b/tests/Query/Aggregation/Builder/CompositeAggregationBuilderTest.php index 9a9cc36..cb8abc8 100644 --- a/tests/Query/Aggregation/Builder/CompositeAggregationBuilderTest.php +++ b/tests/Query/Aggregation/Builder/CompositeAggregationBuilderTest.php @@ -13,7 +13,7 @@ use Kununu\Elasticsearch\Query\RawQuery; use PHPUnit\Framework\TestCase; -class CompositeAggregationBuilderTest extends TestCase +final class CompositeAggregationBuilderTest extends TestCase { public function testCompositeAggregationBuilder(): void { diff --git a/tests/Result/CompositeResultTest.php b/tests/Result/CompositeResultTest.php index 2923113..8dbc12c 100644 --- a/tests/Result/CompositeResultTest.php +++ b/tests/Result/CompositeResultTest.php @@ -16,4 +16,4 @@ public function testCompositeResult(): void self::assertEquals(1, $compositeResult->documentsCount); self::assertEquals('agg', $compositeResult->aggregationName); } -} \ No newline at end of file +} From ea6fa55d46eaf5b12532a24f5a376620c8725090 Mon Sep 17 00:00:00 2001 From: "diogo.correia" Date: Mon, 15 Jul 2024 15:22:02 +0100 Subject: [PATCH 09/10] Changed getter name. --- .../Builder/CompositeAggregationQueryBuilder.php | 13 +++++-------- src/Query/CompositeAggregationQueryInterface.php | 2 +- src/Repository/Repository.php | 4 ++-- .../RepositoryAggregateCompositeByQueryTest.php | 2 +- 4 files changed, 9 insertions(+), 12 deletions(-) diff --git a/src/Query/Aggregation/Builder/CompositeAggregationQueryBuilder.php b/src/Query/Aggregation/Builder/CompositeAggregationQueryBuilder.php index 06c3ea2..73530f1 100644 --- a/src/Query/Aggregation/Builder/CompositeAggregationQueryBuilder.php +++ b/src/Query/Aggregation/Builder/CompositeAggregationQueryBuilder.php @@ -15,17 +15,14 @@ final class CompositeAggregationQueryBuilder implements CompositeAggregationQueryInterface { - private ?array $afterKey; + private ?array $afterKey = null; private Filters $filters; - private ?string $name; - private ?Sources $sources; + private ?string $name = null; + private ?Sources $sources = null; private function __construct() { - $this->afterKey = null; $this->filters = new Filters(); - $this->name = null; - $this->sources = null; } public static function create(): self @@ -61,7 +58,7 @@ public function withSources(Sources $sources): self return $this; } - public function name(): string + public function getName(): string { if (null === $this->name) { throw new MissingAggregationAttributesException('Aggregation name is missing'); @@ -80,7 +77,7 @@ public function getQuery(int $compositeSize = 100): QueryInterface ], ], 'aggs' => [ - $this->name() => [ + $this->getName() => [ 'composite' => [ 'size' => $compositeSize, 'sources' => $this->sources?->map( diff --git a/src/Query/CompositeAggregationQueryInterface.php b/src/Query/CompositeAggregationQueryInterface.php index 29240ad..1f0aabe 100644 --- a/src/Query/CompositeAggregationQueryInterface.php +++ b/src/Query/CompositeAggregationQueryInterface.php @@ -7,7 +7,7 @@ interface CompositeAggregationQueryInterface { public function getQuery(int $compositeSize = 100): QueryInterface; - public function name(): string; + public function getName(): string; public function withName(string $name): self; diff --git a/src/Repository/Repository.php b/src/Repository/Repository.php index c04ccee..9d3564b 100644 --- a/src/Repository/Repository.php +++ b/src/Repository/Repository.php @@ -294,14 +294,14 @@ public function aggregateCompositeByQuery(CompositeAggregationQueryInterface $qu do { $result = $this->aggregateByQuery( $query->withAfterKey($afterKey)->getQuery() - )->getResultByName($query->name()); + )->getResultByName($query->getName()); foreach ($result?->getFields()['buckets'] ?? [] as $bucket) { if (!empty($bucket['key']) && !empty($bucket['doc_count'])) { yield new CompositeResult( $bucket['key'], $bucket['doc_count'], - $query->name() + $query->getName() ); } } diff --git a/tests/Repository/RepositoryAggregateCompositeByQueryTest.php b/tests/Repository/RepositoryAggregateCompositeByQueryTest.php index cf81784..800b136 100644 --- a/tests/Repository/RepositoryAggregateCompositeByQueryTest.php +++ b/tests/Repository/RepositoryAggregateCompositeByQueryTest.php @@ -34,7 +34,7 @@ public function testAggregateCompositeByQuery(): void $compositeQuery ->expects($this->any()) - ->method('name') + ->method('getName') ->willReturn('agg'); $compositeQuery From 4597e805cc6874704fd71bd25762e984fef11a1d Mon Sep 17 00:00:00 2001 From: "diogo.correia" Date: Mon, 15 Jul 2024 19:08:13 +0100 Subject: [PATCH 10/10] Added aggregateCompositeByQuery method signature into RepositoryInterface. --- src/Repository/Repository.php | 1 - src/Repository/RepositoryInterface.php | 9 +++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/Repository/Repository.php b/src/Repository/Repository.php index 9d3564b..2e11613 100644 --- a/src/Repository/Repository.php +++ b/src/Repository/Repository.php @@ -286,7 +286,6 @@ function() use ($query) { ); } - /** @return Generator */ public function aggregateCompositeByQuery(CompositeAggregationQueryInterface $query): Generator { $afterKey = null; diff --git a/src/Repository/RepositoryInterface.php b/src/Repository/RepositoryInterface.php index b7b63bf..203823b 100644 --- a/src/Repository/RepositoryInterface.php +++ b/src/Repository/RepositoryInterface.php @@ -3,6 +3,8 @@ namespace Kununu\Elasticsearch\Repository; +use Generator; +use Kununu\Elasticsearch\Query\CompositeAggregationQueryInterface; use Kununu\Elasticsearch\Query\QueryInterface; use Kununu\Elasticsearch\Result\AggregationResultSetInterface; use Kununu\Elasticsearch\Result\ResultIteratorInterface; @@ -102,6 +104,13 @@ public function countByQuery(QueryInterface $query): int; */ public function aggregateByQuery(QueryInterface $query): AggregationResultSetInterface; + /** + * This method executes a query with composite aggregation, iterates through the results, and retrieves the data. + * + * @return Generator + */ + public function aggregateCompositeByQuery(CompositeAggregationQueryInterface $query): Generator; + /** * This method updates all documents matching a given $query using a given $updateScript. */