diff --git a/doc/04_Searching_For_Data_In_Index/05_Search_Modifiers/README.md b/doc/04_Searching_For_Data_In_Index/05_Search_Modifiers/README.md index 7d00e0d1..dc2f1974 100644 --- a/doc/04_Searching_For_Data_In_Index/05_Search_Modifiers/README.md +++ b/doc/04_Searching_For_Data_In_Index/05_Search_Modifiers/README.md @@ -38,10 +38,11 @@ $search->addModifier(new ParentIdFilter(1)) ### Dependencies -| Modifier | Modifier Category | Description | -|------------------------------------------------------------------------------------------------------------------------------------------------|-------------------|-----------------------------------------------------------| -| [RequiresFilter](https://github.com/pimcore/generic-data-index-bundle/blob/1.x/src/Model/Search/Modifier/Filter/Dependency/RequiresFilter.php) | Dependencies | Get all elements which the given element requires. | -| [RequiredByFilter](https://github.com/pimcore/generic-data-index-bundle/blob/1.x/src/Model/Search/Modifier/Filter/Dependency/RequiredByFilter.php) | Dependencies | Get all elements which are required by the given element. | +| Modifier | Modifier Category | Description | +|------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------|---------------------------------------------------------| +| [RequiresFilter](https://github.com/pimcore/generic-data-index-bundle/blob/1.x/src/Model/Search/Modifier/Filter/Dependency/RequiresFilter.php) | Dependencies | Get all elements which the given element requires. | +| [RequiredByFilter](https://github.com/pimcore/generic-data-index-bundle/blob/1.x/src/Model/Search/Modifier/Filter/Dependency/RequiredByFilter.php) | Dependencies | Get all elements which are required by the given element. | +| [NoDependenciesFilter](https://github.com/pimcore/generic-data-index-bundle/blob/1.x/src/Model/Search/Modifier/Filter/Dependency/NoDependenciesFilter.php) | Dependencies | Get all elements which have no dependencies. | ### Query Language diff --git a/src/Model/Search/Modifier/Filter/Dependency/NoDependenciesFilter.php b/src/Model/Search/Modifier/Filter/Dependency/NoDependenciesFilter.php new file mode 100644 index 00000000..3e5beff6 --- /dev/null +++ b/src/Model/Search/Modifier/Filter/Dependency/NoDependenciesFilter.php @@ -0,0 +1,32 @@ +elementType; + } +} diff --git a/src/SearchIndexAdapter/OpenSearch/Search/Modifier/Filter/DependencyFilters.php b/src/SearchIndexAdapter/OpenSearch/Search/Modifier/Filter/DependencyFilters.php index b05f0fa8..bbf6e3fa 100644 --- a/src/SearchIndexAdapter/OpenSearch/Search/Modifier/Filter/DependencyFilters.php +++ b/src/SearchIndexAdapter/OpenSearch/Search/Modifier/Filter/DependencyFilters.php @@ -24,6 +24,7 @@ use Pimcore\Bundle\GenericDataIndexBundle\Model\OpenSearch\Query\BoolQuery; use Pimcore\Bundle\GenericDataIndexBundle\Model\OpenSearch\Query\TermFilter; use Pimcore\Bundle\GenericDataIndexBundle\Model\OpenSearch\Query\TermsFilter; +use Pimcore\Bundle\GenericDataIndexBundle\Model\Search\Modifier\Filter\Dependency\NoDependenciesFilter; use Pimcore\Bundle\GenericDataIndexBundle\Model\Search\Modifier\Filter\Dependency\RequiredByFilter; use Pimcore\Bundle\GenericDataIndexBundle\Model\Search\Modifier\Filter\Dependency\RequiresFilter; use Pimcore\Bundle\GenericDataIndexBundle\Service\Search\SearchService\Element\ElementSearchServiceInterface; @@ -104,4 +105,23 @@ public function handleRequiresFilter( ]) ); } + + #[AsSearchModifierHandler] + public function handleFilterWithoutDependencies( + NoDependenciesFilter $noDependenciesFilter, + SearchModifierContextInterface $context + ): void { + $boolQuery = new BoolQuery(); + $boolQuery->addCondition( + ConditionType::MUST_NOT->value, + [ + ConditionType::EXISTS->value => [ + 'field' => SystemField::DEPENDENCIES->getPath( + $noDependenciesFilter->getElementType()?->getShortValue() + ), + ], + ] + )->toArray(true); + $context->getSearch()->addQuery($boolQuery); + } } diff --git a/tests/Functional/Search/Modifier/Filter/DependencyFiltersTest.php b/tests/Functional/Search/Modifier/Filter/DependencyFiltersTest.php index 7b85a448..4305ac24 100644 --- a/tests/Functional/Search/Modifier/Filter/DependencyFiltersTest.php +++ b/tests/Functional/Search/Modifier/Filter/DependencyFiltersTest.php @@ -16,9 +16,11 @@ namespace Pimcore\Bundle\GenericDataIndexBundle\Tests\Functional\Search\Modifier\Filter; use Pimcore\Bundle\GenericDataIndexBundle\Enum\SearchIndex\ElementType; +use Pimcore\Bundle\GenericDataIndexBundle\Model\Search\Modifier\Filter\Dependency\NoDependenciesFilter; use Pimcore\Bundle\GenericDataIndexBundle\Model\Search\Modifier\Filter\Dependency\RequiredByFilter; use Pimcore\Bundle\GenericDataIndexBundle\Model\Search\Modifier\Filter\Dependency\RequiresFilter; use Pimcore\Bundle\GenericDataIndexBundle\Service\Search\SearchService\Asset\AssetSearchServiceInterface; +use Pimcore\Bundle\GenericDataIndexBundle\Service\Search\SearchService\DataObject\DataObjectSearchServiceInterface; use Pimcore\Bundle\GenericDataIndexBundle\Service\Search\SearchService\SearchProviderInterface; use Pimcore\Model\DataObject\Unittest; use Pimcore\Tests\Support\Util\TestHelper; @@ -83,6 +85,48 @@ public function testDependencyFilters() $this->assertIdArrayEquals([$object2->getId(), $object3->getId()], $searchResult->getIds()); } + // tests + public function testNoDependencyFilter() + { + /** + * @var Unittest $object1 + * @var Unittest $object2 + * @var Unittest $object3 + * @var Unittest $object4 + */ + $object1 = TestHelper::createEmptyObject(); + $object2 = TestHelper::createEmptyObject(); + $object3 = TestHelper::createEmptyObject(); + $object4 = TestHelper::createEmptyObject(); + + $image1 = TestHelper::createImageAsset(); + + $object1 + ->setObjects([$object2, $object3]) + ->setImage($image1) + ->save() + ; + + $object4->setObjects([$object1])->save(); + + /** @var DataObjectSearchServiceInterface $searchService */ + $searchService = $this->tester->grabService('generic-data-index.test.service.data-object-search-service'); + /** @var SearchProviderInterface $searchProvider */ + $searchProvider = $this->tester->grabService(SearchProviderInterface::class); + + $elementSearch = $searchProvider->createDataObjectSearch()->addModifier(new NoDependenciesFilter()); + $searchResult = $searchService->search($elementSearch); + // Object 2 and 3 have no dependencies + $this->assertIdArrayEquals([$object2->getId(), $object3->getId()], $searchResult->getIds()); + + $elementSearch = $searchProvider->createDataObjectSearch()->addModifier( + new NoDependenciesFilter(ElementType::ASSET) + ); + $searchResult = $searchService->search($elementSearch); + // Only Object 1 has no asset dependencies + $this->assertIdArrayEquals([$object2->getId(), $object3->getId(), $object4->getId()], $searchResult->getIds()); + } + private function assertIdArrayEquals(array $ids1, array $ids2) { sort($ids1);