diff --git a/src/Aggregating/Bucket/ReverseNestedAggregation.php b/src/Aggregating/Bucket/ReverseNestedAggregation.php new file mode 100644 index 0000000..63f6d3f --- /dev/null +++ b/src/Aggregating/Bucket/ReverseNestedAggregation.php @@ -0,0 +1,37 @@ +name; + } + + public function toDSL(): array + { + return [$this->name => [ + 'reverse_nested' => new \stdClass(), + 'aggs' => $this->children->toDSL(), + ]]; + } + + public function parseResults(array $response): array + { + return $this->children + ->parseResults($response[$this->name] ?? []) + ->all(); + } +} diff --git a/tests/IntegrationTests/AggregationQueryIntegrationTest.php b/tests/IntegrationTests/AggregationQueryIntegrationTest.php index d9869c7..ca8a76a 100644 --- a/tests/IntegrationTests/AggregationQueryIntegrationTest.php +++ b/tests/IntegrationTests/AggregationQueryIntegrationTest.php @@ -2,7 +2,9 @@ use Ensi\LaravelElasticQuery\Aggregating\AggregationCollection; use Ensi\LaravelElasticQuery\Aggregating\Bucket; +use Ensi\LaravelElasticQuery\Aggregating\Bucket\ReverseNestedAggregation; use Ensi\LaravelElasticQuery\Aggregating\FiltersCollection; +use Ensi\LaravelElasticQuery\Aggregating\Metrics\CardinalityAggregation; use Ensi\LaravelElasticQuery\Aggregating\Metrics\MinMaxScoreAggregation; use Ensi\LaravelElasticQuery\Aggregating\Metrics\ScriptAggregation; use Ensi\LaravelElasticQuery\Aggregating\Metrics\TopHitsAggregation; @@ -263,3 +265,42 @@ $scores, ); }); + +test('reverse nested aggregation with specific data', function () { + /** @var IntegrationTestCase $this */ + + $results = ProductsIndex::aggregate() + ->where('active', true) + ->nested('offers', function ($builder) { + $reverseAggs = new AggregationCollection(); + $reverseAggs->add(new CardinalityAggregation( + 'product_id', + 'product_id' + )); + $reverseNested = new ReverseNestedAggregation('product_info', $reverseAggs); + + $compositeAggs = new AggregationCollection(); + $compositeAggs->add($reverseNested); + + $builder->terms('sellers', 'seller_id', 10, composite: $compositeAggs); + }) + ->get(); + + $sellers = $results->get('sellers'); + + $seller10Bucket = $sellers->first(fn (Bucket $bucket) => $bucket->key == 10); + expect($seller10Bucket)->not->toBeNull(); + expect($seller10Bucket->getCompositeValue('product_id'))->toBe(3); + + $seller15Bucket = $sellers->first(fn (Bucket $bucket) => $bucket->key == 15); + expect($seller15Bucket)->not->toBeNull(); + expect($seller15Bucket->getCompositeValue('product_id'))->toBe(3); + + $seller20Bucket = $sellers->first(fn (Bucket $bucket) => $bucket->key == 20); + expect($seller20Bucket)->not->toBeNull(); + expect($seller20Bucket->getCompositeValue('product_id'))->toBe(3); + + $seller90Bucket = $sellers->first(fn (Bucket $bucket) => $bucket->key == 90); + expect($seller90Bucket)->not->toBeNull(); + expect($seller90Bucket->getCompositeValue('product_id'))->toBe(1); +});