From 5c24fff1572d6753a8d00d8ad79310723a56a108 Mon Sep 17 00:00:00 2001 From: Bart van Asselt Date: Thu, 25 Apr 2024 11:09:45 +0200 Subject: [PATCH] Write tests for NestedFilteredAggregation --- .../NestedFilteredAggregation.php | 80 +++++++++++++++++++ tests/Unit/FinderTest.php | 70 +++++++++++----- 2 files changed, 132 insertions(+), 18 deletions(-) create mode 100644 src/Domain/Aggregations/NestedFilteredAggregation.php diff --git a/src/Domain/Aggregations/NestedFilteredAggregation.php b/src/Domain/Aggregations/NestedFilteredAggregation.php new file mode 100644 index 00000000..aea08790 --- /dev/null +++ b/src/Domain/Aggregations/NestedFilteredAggregation.php @@ -0,0 +1,80 @@ + + */ + private array $filters; + + private int $size; + + /** + * @param array $filters + */ + public function __construct(string $name, string $field, array $filters, int $size = 10) + { + $this->name = $name; + $this->field = $field; + $this->size = $size; + $this->filters = $filters; + } + + /** + * @return array + */ + public function buildElasticFilters(): array + { + $elasticFilters = []; + foreach ($this->filters as $field => $filterValues) { + $elasticFilters[] = [ + 'terms' => [ + 'variants.' . $field => $filterValues, + ], + ]; + } + + return [ + 'bool' => [ + 'should' => [ + 'bool' => [ + 'must' => $elasticFilters, + ], + ], + ], + ]; + } + + /** + * @return array + */ + public function build(): array + { + return [ + 'nested' => [ + 'path' => 'variants', + ], + 'aggs' => [ + 'filter_variants' => [ + 'filter' => $this->buildElasticFilters(), + 'aggs' => [ + $this->name => [ + 'terms' => [ + 'field' => $this->field, + 'size' => $this->size, + ], + ], + ], + ], + ], + ]; + } +} diff --git a/tests/Unit/FinderTest.php b/tests/Unit/FinderTest.php index 94665b0f..2eb7385d 100644 --- a/tests/Unit/FinderTest.php +++ b/tests/Unit/FinderTest.php @@ -9,6 +9,7 @@ use JeroenG\Explorer\Application\AggregationResult; use JeroenG\Explorer\Application\SearchCommand; use JeroenG\Explorer\Domain\Aggregations\MaxAggregation; +use JeroenG\Explorer\Domain\Aggregations\NestedFilteredAggregation; use JeroenG\Explorer\Domain\Aggregations\TermsAggregation; use JeroenG\Explorer\Domain\Query\Query; use JeroenG\Explorer\Domain\Syntax\Compound\BoolQuery; @@ -83,15 +84,15 @@ public function test_it_accepts_must_should_filter_and_where_queries(): void 'query' => [ 'bool' => [ 'must' => [ - ['match' => ['title' => [ 'query' => 'Lorem Ipsum', 'fuzziness' => 'auto']]], + ['match' => ['title' => ['query' => 'Lorem Ipsum', 'fuzziness' => 'auto']]], ['multi_match' => ['query' => 'fuzzy search', 'fuzziness' => 'auto']], ], 'should' => [ - ['match' => ['text' => [ 'query' => 'consectetur adipiscing elit', 'fuzziness' => 'auto']]], + ['match' => ['text' => ['query' => 'consectetur adipiscing elit', 'fuzziness' => 'auto']]], ], 'filter' => [ - ['term' => ['published' => [ 'value' => true, 'boost' => 1.0]]], - ['term' => ['subtitle' => [ 'value' => 'Dolor sit amet', 'boost' => 1.0]]], + ['term' => ['published' => ['value' => true, 'boost' => 1.0]]], + ['term' => ['subtitle' => ['value' => 'Dolor sit amet', 'boost' => 1.0]]], ['terms' => ['tags' => ['t1', 't2'], 'boost' => 1.0]], ], ], @@ -241,7 +242,7 @@ public function test_it_builds_with_default_fields(): void 'query' => [ 'bool' => [ 'must' => [ - ['multi_match' => ['query' => 'fuzzy search', 'fields' => self::SEARCHABLE_FIELDS, 'fuzziness' => 'auto' ]], + ['multi_match' => ['query' => 'fuzzy search', 'fields' => self::SEARCHABLE_FIELDS, 'fuzziness' => 'auto']], ], 'should' => [], 'filter' => [], @@ -281,7 +282,7 @@ public function test_it_adds_fields_to_query(): void 'filter' => [], ], ], - 'fields' => ['*.length', 'specific.field'] + 'fields' => ['*.length', 'specific.field'], ], ]) ->andReturn([ @@ -331,18 +332,18 @@ public function test_it_adds_aggregates(): void 'aggregations' => [ 'specificAggregation' => [ 'buckets' => [ - ['key' => 'myKey', 'doc_count' => 42] - ] + ['key' => 'myKey', 'doc_count' => 42], + ], ], 'anotherAggregation' => [ 'buckets' => [ - ['key' => 'anotherKey', 'doc_count' => 6] - ] + ['key' => 'anotherKey', 'doc_count' => 6], + ], ], 'metricAggregation' => [ 'value' => 10, - ] - ] + ], + ], ]); $query = Query::with(new BoolQuery()); @@ -402,7 +403,24 @@ public function test_it_adds_nested_aggregations(): void ], ], ], - 'anotherAggregation' => ['terms' => ['field' => 'anotherField', 'size' => 10]] + 'nestedFilteredAggregation' => [ + 'nested' => [ + 'path' => 'nestedFilteredAggregation', + ], + 'aggs' => [ + 'filter_aggs' => [ + 'aggs' => [ + 'someFieldFiltered' => [ + 'terms' => [ + 'field' => 'nestedFilteredAggregation.someField', + 'size' => 10, + ], + ], + ], + ], + ], + ], + 'anotherAggregation' => ['terms' => ['field' => 'anotherField', 'size' => 10]], ], ], ]) @@ -418,14 +436,29 @@ public function test_it_adds_nested_aggregations(): void 'doc_count_error_upper_bound' => 0, 'sum_other_doc_count' => 0, 'buckets' => [ - ['key' => 'someKey', 'doc_count' => 6,] + ['key' => 'someKey', 'doc_count' => 6,], + ], + ], + ], + + 'nestedFilteredAggregation' => [ + 'doc_count' => 42, + 'filter_aggs' => [ + 'doc_count' => 42, + 'someFieldFiltered' => [ + 'doc_count_error_upper_bound' => 0, + 'sum_other_doc_count' => 0, + 'buckets' => [ + ['key' => 'someKey', 'doc_count' => 6,], + ], ], ], ], + 'specificAggregation' => [ 'buckets' => [ - ['key' => 'myKey', 'doc_count' => 42] - ] + ['key' => 'myKey', 'doc_count' => 42], + ], ], ], ]); @@ -434,14 +467,15 @@ public function test_it_adds_nested_aggregations(): void $query->addAggregation('anotherAggregation', new TermsAggregation('anotherField')); $nestedAggregation = new NestedAggregation('nestedAggregation'); $nestedAggregation->add('someField', new TermsAggregation('nestedAggregation.someField')); - $query->addAggregation('nestedAggregation',$nestedAggregation); + $query->addAggregation('nestedAggregation', $nestedAggregation); + $query->addAggregation('anotherAggregation', new NestedFilteredAggregation('filter_aggs', 'nestedFilteredAggregation.someField', [])); $builder = new SearchCommand(self::TEST_INDEX, $query); $builder->setIndex(self::TEST_INDEX); $subject = new Finder($client, $builder); $results = $subject->find(); - self::assertCount(2, $results->aggregations()); + self::assertCount(3, $results->aggregations()); $nestedAggregation = $results->aggregations()[0];