Skip to content

Commit

Permalink
Implement file size aggregation services for assets (#187)
Browse files Browse the repository at this point in the history
  • Loading branch information
markus-moser authored Jul 24, 2024
1 parent 196371f commit beef99f
Show file tree
Hide file tree
Showing 12 changed files with 212 additions and 6 deletions.
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 @@ -30,4 +30,8 @@ services:

Pimcore\Bundle\GenericDataIndexBundle\Service\Transformer\SearchResultItem\DataObjectToSearchResultItemTransformerInterface:
class: Pimcore\Bundle\GenericDataIndexBundle\Service\Transformer\SearchResultItem\DataObjectToSearchResultItemTransformer
public: true

Pimcore\Bundle\GenericDataIndexBundle\Service\Search\SearchService\Asset\Aggregation\FileSizeAggregationServiceInterface:
class: Pimcore\Bundle\GenericDataIndexBundle\Service\Search\SearchService\Asset\Aggregation\FileSizeAggregationService
public: true
3 changes: 3 additions & 0 deletions config/services/search/search-services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ services:
Pimcore\Bundle\GenericDataIndexBundle\Service\Search\SearchService\Element\ElementSearchHelperInterface:
class: Pimcore\Bundle\GenericDataIndexBundle\Service\Search\SearchService\Element\SearchHelper

Pimcore\Bundle\GenericDataIndexBundle\Service\Search\SearchService\Asset\Aggregation\FileSizeAggregationServiceInterface:
class: Pimcore\Bundle\GenericDataIndexBundle\Service\Search\SearchService\Asset\Aggregation\FileSizeAggregationService

Pimcore\Bundle\GenericDataIndexBundle\Service\Search\SearchService\SearchProviderInterface:
class: Pimcore\Bundle\GenericDataIndexBundle\Service\Search\SearchService\SearchProvider

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,11 @@ $search->addModifier(new ParentIdFilter(1))
### Aggregations


| Modifier | Modifier Category | Description |
|--------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------|-------------------------------------------------------------------------------------------------------|
| [ChildrenCountAggregation](https://github.com/pimcore/generic-data-index-bundle/blob/1.x/src/Model/Search/Modifier/Aggregation/Tree/ChildrenCountAggregation.php) | Tree related aggregation | Get children counts for given element IDs. |
| [AssetMetaDataAggregation](https://github.com/pimcore/generic-data-index-bundle/blob/1.x/src/Model/Search/Modifier/Aggregation/Asset/AssetMetaDataAggregation.php) | Assets | Used for the filters in the asset grid to aggregate the filter options for supported meta data types. |
| Modifier | Modifier Category | Description |
|--------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| [ChildrenCountAggregation](https://github.com/pimcore/generic-data-index-bundle/blob/1.x/src/Model/Search/Modifier/Aggregation/Tree/ChildrenCountAggregation.php) | Tree related aggregation | Get children counts for given element IDs. |
| [AssetMetaDataAggregation](https://github.com/pimcore/generic-data-index-bundle/blob/1.x/src/Model/Search/Modifier/Aggregation/Asset/AssetMetaDataAggregation.php) | Assets | Used for the filters in the asset grid to aggregate the filter options for supported meta data types. |
| [FileSizeSumAggregation](https://github.com/pimcore/generic-data-index-bundle/blob/1.x/src/Model/Search/Modifier/Aggregation/Asset/FileSizeSumAggregation.php) | Assets | Aggregates the sum of file sizes for all assets for a given search. The `FileSizeAggregationServiceInterface` internally uses this aggregation and provides an easy way to use this functionality. |

## Add your own search modifier

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ public function isHasChildren(): bool
$this->lazyLoad();
}

return $this->hasChildren;
return $this->hasChildren ?? false;
}

public function setHasChildren(bool $hasChildren): AssetSearchResultItem
Expand Down
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\Model\Search\Modifier\Aggregation\Asset;

use Pimcore\Bundle\GenericDataIndexBundle\Model\Search\Modifier\SearchModifierInterface;

final readonly class FileSizeSumAggregation implements SearchModifierInterface
{
public function __construct(
private string $aggregationName,
) {
}

public function getAggregationName(): string
{
return $this->aggregationName;
}
}
6 changes: 6 additions & 0 deletions src/Model/SearchIndexAdapter/SearchResultAggregation.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ public function __construct(
private array $buckets,
private int $otherDocCount,
private int $docCountErrorUpperBound,
private array $aggregationResult = [],
) {
}

Expand All @@ -46,4 +47,9 @@ public function getDocCountErrorUpperBound(): int
{
return $this->docCountErrorUpperBound;
}

public function getAggregationResult(): array
{
return $this->aggregationResult;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
readonly class SearchResultAggregationBucket
{
public function __construct(
private string|int $key,
private string|int|float $key,
private int $docCount,
) {
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,11 @@

use Pimcore\Bundle\GenericDataIndexBundle\Attribute\OpenSearch\AsSearchModifierHandler;
use Pimcore\Bundle\GenericDataIndexBundle\Exception\InvalidModifierException;
use Pimcore\Bundle\GenericDataIndexBundle\Model\OpenSearch\Aggregation\Aggregation;
use Pimcore\Bundle\GenericDataIndexBundle\Model\OpenSearch\Modifier\SearchModifierContextInterface;
use Pimcore\Bundle\GenericDataIndexBundle\Model\Search\Asset\AssetSearch;
use Pimcore\Bundle\GenericDataIndexBundle\Model\Search\Modifier\Aggregation\Asset\AssetMetaDataAggregation;
use Pimcore\Bundle\GenericDataIndexBundle\Model\Search\Modifier\Aggregation\Asset\FileSizeSumAggregation;
use Pimcore\Bundle\GenericDataIndexBundle\SearchIndexAdapter\Asset\FieldDefinitionServiceInterface;
use Pimcore\Twig\Extension\Templating\Placeholder\Exception;

Expand Down Expand Up @@ -64,4 +67,25 @@ public function handleAssetMetaDataAggregation(
throw new InvalidModifierException($e->getMessage(), 0, $e);
}
}

#[AsSearchModifierHandler]
public function handleFileSizeAggregation(
FileSizeSumAggregation $aggregation,
SearchModifierContextInterface $context
): void {
if (!$context->getOriginalSearch() instanceof AssetSearch) {
throw new InvalidModifierException('FileSizeAggregation can only be used with AssetSearch');
}

$context->getSearch()->addAggregation(
new Aggregation(
name: $aggregation->getAggregationName(),
params: [
'sum' => [
'field' => 'system_fields.fileSize',
],
]
)
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?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\Asset\Aggregation;

use Pimcore\Bundle\GenericDataIndexBundle\Model\Search\Asset\AssetSearch;
use Pimcore\Bundle\GenericDataIndexBundle\Model\Search\Modifier\Aggregation\Asset\FileSizeSumAggregation;
use Pimcore\Bundle\GenericDataIndexBundle\Service\Search\SearchService\Asset\AssetSearchServiceInterface;

/**
* @internal
*/
final readonly class FileSizeAggregationService implements FileSizeAggregationServiceInterface
{
public function __construct(
private AssetSearchServiceInterface $assetSearchService,
) {
}

public function getFileSizeSum(AssetSearch $assetSearch): int
{
$aggregation = new FileSizeSumAggregation('fileSizeSum');
$assetSearch
->addModifier($aggregation)
->setAggregationsOnly(true)
;

$result = $this->assetSearchService->search($assetSearch);

$sum = $result->getAggregation($aggregation->getAggregationName())?->getAggregationResult()['value'] ?? 0;

return (int) $sum;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?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\Asset\Aggregation;

use Pimcore\Bundle\GenericDataIndexBundle\Model\Search\Asset\AssetSearch;

interface FileSizeAggregationServiceInterface
{
/**
* Returns the sum of the file sizes of all assets that match the given search criteria in bytes.
*/
public function getFileSizeSum(AssetSearch $assetSearch): int;
}
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ private function hydrateAggregations(array $aggregations): array
buckets: $this->hydrateAggregationBuckets($aggregation['buckets'] ?? []),
otherDocCount: $aggregation['sum_other_doc_count'] ?? 0,
docCountErrorUpperBound: $aggregation['doc_count_error_upper_bound'] ?? 0,
aggregationResult: $aggregation,
);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?php

/**
* 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\Tests\Functional\Search\SearchService\Asset\Aggregation;

use Pimcore\Bundle\GenericDataIndexBundle\Model\Search\Asset\AssetSearch;
use Pimcore\Bundle\GenericDataIndexBundle\Model\Search\Modifier\Filter\Basic\IdsFilter;
use Pimcore\Bundle\GenericDataIndexBundle\Service\Search\SearchService\Asset\Aggregation\FileSizeAggregationServiceInterface;
use Pimcore\Tests\Support\Util\TestHelper;

final class FileSizeAggregationServiceTest extends \Codeception\Test\Unit
{
/**
* @var \Pimcore\Bundle\GenericDataIndexBundle\Tests\IndexTester
*/
protected $tester;

protected function _before()
{
$this->tester->enableSynchronousProcessing();
}

protected function _after()
{
TestHelper::cleanUp();
$this->tester->flushIndex();
$this->tester->cleanupIndex();
$this->tester->flushIndex();
}

public function testGetFileSizeSum(): void
{
$asset = TestHelper::createImageAsset();
$asset2 = TestHelper::createImageAsset();
$asset3 = TestHelper::createImageAsset();

/** @var FileSizeAggregationServiceInterface $fileSizeAggregationService */
$fileSizeAggregationService = $this->tester->grabService(FileSizeAggregationServiceInterface::class);

$fileSizeSum = $asset->getFileSize() + $asset2->getFileSize() + $asset3->getFileSize();

$assetSearch = (new AssetSearch())
->addModifier(new IdsFilter([$asset->getId(), $asset2->getId(), $asset3->getId()]))
->setPageSize(3);

$this->assertEquals($fileSizeSum, $fileSizeAggregationService->getFileSizeSum($assetSearch));
$this->assertNotSame(0, $fileSizeSum);
}
}

0 comments on commit beef99f

Please sign in to comment.