Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/ci/files/config/services_test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,8 @@ services:

Pimcore\Bundle\GenericDataIndexBundle\SearchIndexAdapter\Search\LocateInTreeServiceInterface:
class: Pimcore\Bundle\GenericDataIndexBundle\SearchIndexAdapter\OpenSearch\Search\LocateInTreeService
public: true

Pimcore\Bundle\GenericDataIndexBundle\Service\Search\SearchService\SearchResultIdListServiceInterface:
class: Pimcore\Bundle\GenericDataIndexBundle\Service\Search\SearchService\SearchResultIdListService
public: true
3 changes: 3 additions & 0 deletions config/services/search-index-adapter/open-search.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ services:
Pimcore\Bundle\GenericDataIndexBundle\SearchIndexAdapter\Search\LocateInTreeServiceInterface:
class: Pimcore\Bundle\GenericDataIndexBundle\SearchIndexAdapter\OpenSearch\Search\LocateInTreeService

Pimcore\Bundle\GenericDataIndexBundle\SearchIndexAdapter\Search\FetchIdsServiceInterface:
class: Pimcore\Bundle\GenericDataIndexBundle\SearchIndexAdapter\OpenSearch\Search\FetchIdsService

Pimcore\Bundle\GenericDataIndexBundle\SearchIndexAdapter\OpenSearch\Search\FetchIdsBySearchServiceInterface:
class: Pimcore\Bundle\GenericDataIndexBundle\SearchIndexAdapter\OpenSearch\Search\FetchIdsBySearchService

Expand Down
6 changes: 6 additions & 0 deletions config/services/search/search-services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,9 @@ services:

Pimcore\Bundle\GenericDataIndexBundle\Service\Search\SearchService\IndexNameResolverInterface:
class: Pimcore\Bundle\GenericDataIndexBundle\Service\Search\SearchService\IndexNameResolver

Pimcore\Bundle\GenericDataIndexBundle\Service\Search\SearchService\TransformToAdapterSearchServiceInterface:
class: Pimcore\Bundle\GenericDataIndexBundle\Service\Search\SearchService\TransformToAdapterSearchService

Pimcore\Bundle\GenericDataIndexBundle\Service\Search\SearchService\SearchResultIdListServiceInterface:
class: Pimcore\Bundle\GenericDataIndexBundle\Service\Search\SearchService\SearchResultIdListService
23 changes: 23 additions & 0 deletions doc/04_Searching_For_Data_In_Index/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,29 @@ public function searchAction(SearchProviderInterface $searchProvider, ElementSea
To influence the data which gets fetched its possible to use so-called search modifiers.
Find out details about search modifiers in the [search modifiers documentation](05_Search_Modifiers/README.md). There you will also find information on how to create your own custom search modifiers.

## Retrieve IDs only instead of full objects

If you only want to retrieve your search results as list of IDs for your `AssetSearch`, `DataObjectSearch` or `DocumentSearch` you can use the `SearchResultIdListServiceInterface` to retrieve the IDs only.

```php
use Pimcore\Bundle\GenericDataIndexBundle\Model\Search\Modifier\Filter\Tree\ParentIdFilter;
use Pimcore\Bundle\GenericDataIndexBundle\Model\Search\Modifier\Sort\Tree\OrderByFullPath;
use Pimcore\Bundle\GenericDataIndexBundle\Service\Search\SearchService\SearchProviderInterface;
use Pimcore\Bundle\GenericDataIndexBundle\Service\Search\SearchService\SearchResultIdListServiceInterface;

public function searchAction(SearchProviderInterface $searchProvider, SearchResultIdListServiceInterface $searchResultIdListService)
{
$dataObjectSearch = $searchProvider->createDataObjectSearch()
->addModifier(new ParentIdFilter(1))
->addModifier(new OrderByFullPath())
->setPageSize(50)
->setPage(1);

$allIds = $searchResultIdListService->getAllIds($dataObjectSearch); // returns an ordered array of IDs for the full search result without pagination
$idsOnPage = $searchResultIdListService->getIdsForCurrentPage($dataObjectSearch); // returns an ordered array of IDs for the current page
}
```

## OpenSearch Search Models
The search services mentioned above offer a flexible and structured way to search for assets, data objects and documents. Nevertheless if there are requirements which are not covered by the search services it might be needed to develop your own customized open search queries. The OpenSearch search models offer a streamlined way for executing such customized search queries. They are also used by the search services internally to create the executed OpenSearch search queries.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ public function __construct(

public function fetchAllIds(OpenSearchSearchInterface $search, string $indexName, bool $sortById = true): array
{
$search = clone $search;
if ($sortById) {
$search->setSortList(new FieldSortList([new FieldSort(SystemField::ID->getPath())]));
}
Expand Down
63 changes: 63 additions & 0 deletions src/SearchIndexAdapter/OpenSearch/Search/FetchIdsService.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<?php
declare(strict_types=1);

/**
* Pimcore
*
* This source file is available under two different licenses:
* - GNU General Public License version 3 (GPLv3)
* - Pimcore Commercial License (PCL)
* Full copyright and license information is available in
* LICENSE.md which is distributed with this source code.
*
* @copyright Copyright (c) Pimcore GmbH (http://www.pimcore.org)
* @license http://www.pimcore.org/license GPLv3 and PCL
*/

namespace Pimcore\Bundle\GenericDataIndexBundle\SearchIndexAdapter\OpenSearch\Search;

use Pimcore\Bundle\GenericDataIndexBundle\Exception\InvalidArgumentException;
use Pimcore\Bundle\GenericDataIndexBundle\Model\OpenSearch\OpenSearchSearchInterface;
use Pimcore\Bundle\GenericDataIndexBundle\Model\Search\Interfaces\AdapterSearchInterface;
use Pimcore\Bundle\GenericDataIndexBundle\SearchIndexAdapter\Search\FetchIdsServiceInterface;
use Pimcore\Bundle\GenericDataIndexBundle\SearchIndexAdapter\SearchIndexServiceInterface;

/**
* @internal
*/
final readonly class FetchIdsService implements FetchIdsServiceInterface
{
public function __construct(
private FetchIdsBySearchServiceInterface $fetchIdsBySearchService,
private SearchIndexServiceInterface $searchIndexService,
) {
}

public function fetchIdsForCurrentPage(AdapterSearchInterface $search, string $indexName): array
{
$search = $this->validateSearch($search);
$search = clone $search;
$search->setSource(false);

return $this->searchIndexService
->search($search, $indexName)
->getIds()
;
}

public function fetchAllIds(AdapterSearchInterface $search, string $indexName, bool $sortById = true): array
{
$search = $this->validateSearch($search);

return $this->fetchIdsBySearchService->fetchAllIds($search, $indexName, $sortById);
}

private function validateSearch(AdapterSearchInterface $search): OpenSearchSearchInterface
{
if (!$search instanceof OpenSearchSearchInterface) {
throw new InvalidArgumentException('Search must be an instance of OpenSearchSearchInterface');
}

return $search;
}
}
29 changes: 29 additions & 0 deletions src/SearchIndexAdapter/Search/FetchIdsServiceInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php
declare(strict_types=1);

/**
* Pimcore
*
* This source file is available under two different licenses:
* - GNU General Public License version 3 (GPLv3)
* - Pimcore Commercial License (PCL)
* Full copyright and license information is available in
* LICENSE.md which is distributed with this source code.
*
* @copyright Copyright (c) Pimcore GmbH (http://www.pimcore.org)
* @license http://www.pimcore.org/license GPLv3 and PCL
*/

namespace Pimcore\Bundle\GenericDataIndexBundle\SearchIndexAdapter\Search;

use Pimcore\Bundle\GenericDataIndexBundle\Model\Search\Interfaces\AdapterSearchInterface;

/**
* @internal
*/
interface FetchIdsServiceInterface
{
public function fetchIdsForCurrentPage(AdapterSearchInterface $search, string $indexName): array;

public function fetchAllIds(AdapterSearchInterface $search, string $indexName, bool $sortById = true): array;
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

namespace Pimcore\Bundle\GenericDataIndexBundle\Service\Search\SearchService\Element;

use Pimcore\Bundle\GenericDataIndexBundle\Model\Search\Interfaces\AdapterSearchInterface;
use Pimcore\Bundle\GenericDataIndexBundle\Model\Search\Interfaces\SearchInterface;
use Pimcore\Bundle\GenericDataIndexBundle\Model\SearchIndexAdapter\SearchResult;
use Pimcore\Model\User;
Expand All @@ -28,6 +29,12 @@ public function addSearchRestrictions(SearchInterface $search): SearchInterface;

public function performSearch(SearchInterface $search, string $indexName): SearchResult;

public function createAdapterSearch(
SearchInterface $search,
string $indexName,
bool $enableOrderByPageNumber = false
): AdapterSearchInterface;

public function hydrateSearchResultHits(
SearchResult $searchResult,
array $childrenCounts,
Expand Down
6 changes: 6 additions & 0 deletions src/Service/Search/SearchService/IndexNameResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@

namespace Pimcore\Bundle\GenericDataIndexBundle\Service\Search\SearchService;

use Pimcore\Bundle\GenericDataIndexBundle\Enum\SearchIndex\IndexName;
use Pimcore\Bundle\GenericDataIndexBundle\Exception\InvalidArgumentException;
use Pimcore\Bundle\GenericDataIndexBundle\Model\Search\Asset\AssetSearch;
use Pimcore\Bundle\GenericDataIndexBundle\Model\Search\DataObject\DataObjectSearch;
use Pimcore\Bundle\GenericDataIndexBundle\Model\Search\Document\DocumentSearch;
use Pimcore\Bundle\GenericDataIndexBundle\Model\Search\Element\ElementSearch;
use Pimcore\Bundle\GenericDataIndexBundle\Model\Search\Interfaces\SearchInterface;
use Pimcore\Bundle\GenericDataIndexBundle\Service\SearchIndex\IndexService\ElementTypeAdapter\AssetTypeAdapter;
use Pimcore\Bundle\GenericDataIndexBundle\Service\SearchIndex\IndexService\ElementTypeAdapter\DataObjectTypeAdapter;
Expand Down Expand Up @@ -51,6 +53,10 @@ public function resolveIndexName(SearchInterface $search): string
return $this->documentTypeAdapter->getAliasIndexName();
}

if ($search instanceof ElementSearch) {
return IndexName::ELEMENT_SEARCH->value;
}

throw new InvalidArgumentException('Unsupported search type: ' . get_class($search));
}
}
78 changes: 78 additions & 0 deletions src/Service/Search/SearchService/SearchResultIdListService.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<?php
declare(strict_types=1);

/**
* Pimcore
*
* This source file is available under two different licenses:
* - GNU General Public License version 3 (GPLv3)
* - Pimcore Commercial License (PCL)
* Full copyright and license information is available in
* LICENSE.md which is distributed with this source code.
*
* @copyright Copyright (c) Pimcore GmbH (http://www.pimcore.org)
* @license http://www.pimcore.org/license GPLv3 and PCL
*/

namespace Pimcore\Bundle\GenericDataIndexBundle\Service\Search\SearchService;

use Pimcore\Bundle\GenericDataIndexBundle\Exception\InvalidArgumentException;
use Pimcore\Bundle\GenericDataIndexBundle\Model\Search\Asset\AssetSearch;
use Pimcore\Bundle\GenericDataIndexBundle\Model\Search\DataObject\DataObjectSearch;
use Pimcore\Bundle\GenericDataIndexBundle\Model\Search\Document\DocumentSearch;
use Pimcore\Bundle\GenericDataIndexBundle\Model\Search\Element\ElementSearch;
use Pimcore\Bundle\GenericDataIndexBundle\Model\Search\Interfaces\SearchInterface;
use Pimcore\Bundle\GenericDataIndexBundle\SearchIndexAdapter\Search\FetchIdsServiceInterface;

/**
* @internal
*/
final readonly class SearchResultIdListService implements SearchResultIdListServiceInterface
{
public function __construct(
private TransformToAdapterSearchServiceInterface $transformToAdapterSearchService,
private IndexNameResolverInterface $indexNameResolver,
private FetchIdsServiceInterface $fetchIdsService,
) {
}

public function getAllIds(SearchInterface $search): array
{
$this->validateSearch($search);

return $this->fetchIdsService->fetchAllIds(
$this->transformToAdapterSearchService->transform($search, true),
$this->indexNameResolver->resolveIndexName($search)
);
}

public function getIdsForCurrentPage(SearchInterface $search): array
{
$this->validateSearch($search);

return $this->fetchIdsService->fetchIdsForCurrentPage(
$this->transformToAdapterSearchService->transform($search),
$this->indexNameResolver->resolveIndexName($search)
);
}

private function validateSearch(SearchInterface $search): void
{
if ($search instanceof AssetSearch
|| $search instanceof DataObjectSearch
|| $search instanceof DocumentSearch
) {
return;
}

if ($search instanceof ElementSearch) {
throw new InvalidArgumentException(
'ElementSearch is not supported by SearchResultIdListService as it might return different element types. Use ElementSearchService instead.'
);
}

throw new InvalidArgumentException(
'SearchInterface must be an instance of AssetSearch, DataObjectSearch or DocumentSearch'
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php
declare(strict_types=1);

/**
* Pimcore
*
* This source file is available under two different licenses:
* - GNU General Public License version 3 (GPLv3)
* - Pimcore Commercial License (PCL)
* Full copyright and license information is available in
* LICENSE.md which is distributed with this source code.
*
* @copyright Copyright (c) Pimcore GmbH (http://www.pimcore.org)
* @license http://www.pimcore.org/license GPLv3 and PCL
*/

namespace Pimcore\Bundle\GenericDataIndexBundle\Service\Search\SearchService;

use Pimcore\Bundle\GenericDataIndexBundle\Model\Search\Interfaces\SearchInterface;

interface SearchResultIdListServiceInterface
{
/**
* Returns all IDs for all pages that match the search criteria ordered by ID.
*/
public function getAllIds(SearchInterface $search): array;

/**
* Returns the IDs for the current page that match the search criteria ordered by defined sort order.
*/
public function getIdsForCurrentPage(SearchInterface $search): array;
}
22 changes: 18 additions & 4 deletions src/Service/Search/SearchService/Traits/SearchHelperTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

namespace Pimcore\Bundle\GenericDataIndexBundle\Service\Search\SearchService\Traits;

use Pimcore\Bundle\GenericDataIndexBundle\Model\Search\Interfaces\AdapterSearchInterface;
use Pimcore\Bundle\GenericDataIndexBundle\Model\Search\Interfaces\SearchInterface;
use Pimcore\Bundle\GenericDataIndexBundle\Model\Search\Modifier\Sort\OrderByPageNumber;
use Pimcore\Bundle\GenericDataIndexBundle\Model\SearchIndexAdapter\SearchResult;
Expand All @@ -28,18 +29,31 @@ trait SearchHelperTrait
{
public function performSearch(SearchInterface $search, string $indexName): SearchResult
{
$adapterSearch = $this->createAdapterSearch($search, $indexName, true);

return $this
->searchIndexService
->search($adapterSearch, $indexName);
}

public function createAdapterSearch(
SearchInterface $search,
string $indexName,
bool $enableOrderByPageNumber = false
): AdapterSearchInterface {
$adapterSearch = $this->searchIndexService->createPaginatedSearch(
$search->getPage(),
$search->getPageSize(),
$search->isAggregationsOnly()
);

$search->addModifier(new OrderByPageNumber($indexName, $search));
if ($enableOrderByPageNumber) {
$search->addModifier(new OrderByPageNumber($indexName, $search));
}

$this->searchModifierService->applyModifiersFromSearch($search, $adapterSearch);

return $this
->searchIndexService
->search($adapterSearch, $indexName);
return $adapterSearch;
}

public function hydrateSearchResultHits(
Expand Down
Loading