From 9189c9ed1c0024b08dd6118c6f486292a7953741 Mon Sep 17 00:00:00 2001 From: Matthias Richter Date: Wed, 11 Dec 2024 16:36:50 +0100 Subject: [PATCH 1/2] Adjust tests --- Tests/Unit/Common/QueryParamsBuilderTest.php | 185 ++++++++++++++++++- 1 file changed, 175 insertions(+), 10 deletions(-) diff --git a/Tests/Unit/Common/QueryParamsBuilderTest.php b/Tests/Unit/Common/QueryParamsBuilderTest.php index 8fce96b..c80de4b 100644 --- a/Tests/Unit/Common/QueryParamsBuilderTest.php +++ b/Tests/Unit/Common/QueryParamsBuilderTest.php @@ -22,8 +22,10 @@ final class QueryParamsBuilderTest extends UnitTestCase const EX_EXTENSION2 = 'ex-extension2'; const EX_FIELD1 = 'ex-field1'; const EX_FIELD2 = 'ex-field2'; + const EX_FIELD3 = 'ex-field3'; const EX_PAGE = 3; const EX_SCRIPT = 'ex-script'; + const EX_PATH = 'ex-path'; private QueryParamsBuilder $subject; private array $settings = []; @@ -61,8 +63,13 @@ protected function setUp(): void ], 1 => [ 'field' => self::EX_FIELD2, + 'type' => 'keyword', + ], + 2 => [ + 'field' => self::EX_FIELD3, 'type' => 'nested', - 'script' => self::EX_SCRIPT + 'script' => self::EX_SCRIPT, + 'path' => self::EX_PATH ] ] ], @@ -77,8 +84,7 @@ protected function setUp(): void ], 1 => [ 'field' => self::EX_FIELD2, - 'type' => 'nested', - 'script' => self::EX_SCRIPT + 'type' => 'keyword' ] ] ] @@ -152,8 +158,13 @@ public function IndexParamIsProcessedCorrectly(): void ] ], self::EX_FIELD2 => [ + 'terms' => [ + 'field' => self::EX_FIELD2 + ] + ], + self::EX_FIELD3 => [ 'nested' => [ - 'path' => self::EX_FIELD2 + 'path' => self::EX_FIELD3 ], 'aggs' => [ 'names' => [ @@ -223,13 +234,13 @@ public function pageParamIsProcessedCorrectly(): void /** * @test */ - public function filterParamIsProcessedCorrectly(): void + public function termsFilterParamIsProcessedCorrectly(): void { $this->subject-> setSettings($this->settings)-> setSearchParams([ 'index' => self:: EX_INDEX, - 'f_filter' => self::EX_VAL + 'f_' . self::EX_FIELD1 => self::EX_VAL ]); GeneralUtility::addInstance(ExtensionConfiguration::class, $this->extConf); @@ -252,8 +263,13 @@ public function filterParamIsProcessedCorrectly(): void ] ], self::EX_FIELD2 => [ + 'terms' => [ + 'field' => self::EX_FIELD2 + ] + ], + self::EX_FIELD3 => [ 'nested' => [ - 'path' => self::EX_FIELD2 + 'path' => self::EX_FIELD3 ], 'aggs' => [ 'names' => [ @@ -275,7 +291,156 @@ public function filterParamIsProcessedCorrectly(): void ], 'filter' => [ [ 'term' => [ - 'filter.keyword' => self::EX_VAL + self::EX_FIELD1 . '.keyword' => self::EX_VAL + ] + ] + ] + ] + ] + ] + ]; + + self::assertEquals($expected, $this->subject->getQueryParams()); + } + + /** + * @test + */ + public function keywordFilterParamIsProcessedCorrectly(): void + { + $this->subject-> + setSettings($this->settings)-> + setSearchParams([ + 'index' => self:: EX_INDEX, + 'f_' . self::EX_FIELD2 => self::EX_VAL + ]); + GeneralUtility::addInstance(ExtensionConfiguration::class, $this->extConf); + + $expected = [ + 'index' => self::EX_INDEX, + 'size' => PaginatorTest::ITEMS_PER_PAGE, + 'body' => [ + '_source' => [ + QueryParamsBuilder::TYPE_FIELD, + QueryParamsBuilder::HEADER_FIELD, + QueryParamsBuilder::BODY_FIELD, + QueryParamsBuilder::FOOTER_FIELD, + QueryParamsBuilder::SEARCHABLE_FIELD + + ], + 'aggs' => [ + self::EX_FIELD1 => [ + 'terms' => [ + 'field' => self::EX_FIELD1 . '.keyword' + ] + ], + self::EX_FIELD2 => [ + 'terms' => [ + 'field' => self::EX_FIELD2 + ] + ], + self::EX_FIELD3 => [ + 'nested' => [ + 'path' => self::EX_FIELD3 + ], + 'aggs' => [ + 'names' => [ + 'terms' => [ + 'script' => [ + 'source' => self::EX_SCRIPT, + 'lang' => 'painless' + ], + 'size' => 15 + ] + ] + ] + ] + ], + 'query' => [ + 'bool' => [ + 'must' => [ + [ 'match_all' => new \StdClass() ] + ], + 'filter' => [ + [ 'term' => [ + self::EX_FIELD2 => self::EX_VAL + ] + ] + ] + ] + ] + ] + ]; + + self::assertEquals($expected, $this->subject->getQueryParams()); + } + + /** + * @test + */ + public function nestedFilterParamIsProcessedCorrectly(): void + { + $this->subject-> + setSettings($this->settings)-> + setSearchParams([ + 'index' => self:: EX_INDEX, + 'f_' . self::EX_FIELD3 => self::EX_VAL + ]); + GeneralUtility::addInstance(ExtensionConfiguration::class, $this->extConf); + + $expected = [ + 'index' => self::EX_INDEX, + 'size' => PaginatorTest::ITEMS_PER_PAGE, + 'body' => [ + '_source' => [ + QueryParamsBuilder::TYPE_FIELD, + QueryParamsBuilder::HEADER_FIELD, + QueryParamsBuilder::BODY_FIELD, + QueryParamsBuilder::FOOTER_FIELD, + QueryParamsBuilder::SEARCHABLE_FIELD + + ], + 'aggs' => [ + self::EX_FIELD1 => [ + 'terms' => [ + 'field' => self::EX_FIELD1 . '.keyword' + ] + ], + self::EX_FIELD2 => [ + 'terms' => [ + 'field' => self::EX_FIELD2 + ] + ], + self::EX_FIELD3 => [ + 'nested' => [ + 'path' => self::EX_FIELD3 + ], + 'aggs' => [ + 'names' => [ + 'terms' => [ + 'script' => [ + 'source' => self::EX_SCRIPT, + 'lang' => 'painless' + ], + 'size' => 15 + ] + ] + ] + ] + ], + 'query' => [ + 'bool' => [ + 'must' => [ + [ 'match_all' => new \StdClass() ] + ], + 'filter' => [ + [ 'nested' => [ + 'path' => self::EX_FIELD3, + 'query' => [ + 'match' => [ + self::EX_FIELD3 . '.' . self::EX_PATH => self::EX_VAL + ] + ] ] ] ] @@ -296,7 +461,7 @@ public function countQueryIsBuiltCorrectly(): void setSettings($this->settings)-> setSearchParams([ 'index' => self:: EX_INDEX, - 'f_filter' => self::EX_VAL + 'f_' . self::EX_FIELD1 => self::EX_VAL ]); $expected = [ @@ -309,7 +474,7 @@ public function countQueryIsBuiltCorrectly(): void ], 'filter' => [ [ 'term' => [ - 'filter.keyword' => self::EX_VAL + self::EX_FIELD1 . '.keyword' => self::EX_VAL ] ] ] From 7b5101a9969949d5180fef646be9ae926d143935 Mon Sep 17 00:00:00 2001 From: Matthias Richter Date: Wed, 11 Dec 2024 16:37:07 +0100 Subject: [PATCH 2/2] Adjust filter calculation --- Classes/Common/QueryParamsBuilder.php | 96 ++++++++++++++------------- 1 file changed, 50 insertions(+), 46 deletions(-) diff --git a/Classes/Common/QueryParamsBuilder.php b/Classes/Common/QueryParamsBuilder.php index 8ab7fe3..939389b 100644 --- a/Classes/Common/QueryParamsBuilder.php +++ b/Classes/Common/QueryParamsBuilder.php @@ -226,33 +226,34 @@ private static function getAggs(array $settings, string $index): array private static function getFilter(array $field): array { -/* if ( isset($field['type']) && $field['type'] == 'terms' ) { -*/ return [ 'term' => [ - $field['name']. '.keyword' => $field['value'] + $field['name'] . '.keyword' => $field['value'] ] ]; - //} + } + + if ( + isset($field['type']) && + $field['type'] == 'keyword' + ) { + return [ + 'term' => [ + $field['name'] => $field['value'] + ] + ]; + } return [ - $field['name'] => [ - 'nested' => [ - 'path' => $field['name'] - ], - 'aggs' => [ - 'names' => [ - 'terms' => [ - 'script' => [ - 'source' => $field['script'], - 'lang' => 'painless' - ], - 'size' => 15, - ] + 'nested' => [ + 'path' => $field['name'], + 'query' => [ + 'match' => [ + $field['name'] . '.' . $field['path'] => $field['value'] ] ] ] @@ -265,7 +266,8 @@ private static function getFilter(array $field): array private function setCommonParams(): void { // set index name - $this->query['index'] = $this->indexName; + $index = $this->indexName; + $this->query['index'] = $index; // set body if (!isset($this->params['searchText']) || $this->params['searchText'] == '') { @@ -302,34 +304,36 @@ private function setCommonParams(): void } // set filters - $query = $this->query; - Collection::wrap($this->params)-> - filter(function($_, $key) { return Str::of($key)->startsWith('f_'); })-> - each(function($value, $key) use (&$query) { - $field = Str::of($key)->replace('f_', '')->__toString(); - if ($field !== 'creators') { - $query['body']['query']['bool']['filter'][] = self::getFilter([ - 'name' => $field, - //'type' => $field['type'], - 'type' => 'terms', - 'value' => $value - ]); - } else { - // its not a filter query because they need 100% match (with spaces from f_creators_name) - // better would be to build the field 'fullName' at build time with PHP? - $query['body']['query']['bool']['must'][] = [ - 'nested' => [ - 'path' => 'creators', - 'query' => [ - 'match' => [ - 'creators.fullName' => $value - ] - ] - ] - ]; - } - }); - $this->query = $query; + if ($this->searchAll == false) { + $filterTypes = Collection::wrap($this->settings)-> + recursive()-> + get('entityTypes')-> + filter(function($entityType) use ($index) {return $entityType->get('indexName') === $index;})-> + values()-> + get(0)-> + get('filters')-> + mapWithKeys(function($filter) { return [ + $filter['field'] => [ + 'type' => $filter['type'], + 'path' => isset($filter['path']) ? $filter['path'] : '' + ]]; + })-> + all(); + + $query = $this->query; + Collection::wrap($this->params)-> + filter(function($_, $key) { return Str::of($key)->startsWith('f_'); })-> + each(function($value, $key) use (&$query, $filterTypes) { + $field = Str::of($key)->replace('f_', '')->__toString(); + $query['body']['query']['bool']['filter'][] = self::getFilter([ + 'name' => $field, + 'type' => $filterTypes[$field]['type'], + 'value' => $value, + 'path' => $filterTypes[$field]['path'] + ]); + }); + $this->query = $query; + } }