Skip to content

Commit

Permalink
IDBPR-2901 Add TopHits v7
Browse files Browse the repository at this point in the history
  • Loading branch information
egmanoylin committed Feb 20, 2025
1 parent 053fecb commit bf7a735
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 0 deletions.
49 changes: 49 additions & 0 deletions src/Aggregating/Metrics/TopHitsAggregation.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?php

namespace Ensi\LaravelElasticQuery\Aggregating\Metrics;

use Ensi\LaravelElasticQuery\Contracts\Aggregation;
use Ensi\LaravelElasticQuery\Search\Sorting\SortCollection;
use stdClass;
use Webmozart\Assert\Assert;

class TopHitsAggregation implements Aggregation
{
public function __construct(
private string $name,
private ?int $size = null,
protected ?SortCollection $sort = null,
) {
Assert::stringNotEmpty(trim($name));
Assert::nullOrGreaterThan($this->size, 0);
}

public function name(): string
{
return $this->name;
}

public function parseResults(array $response): array
{
return [$this->name => $response[$this->name]['hits']['hits'] ?? []];
}

public function toDSL(): array
{
$body = [];

if ($this->size !== null) {
$body['size'] = $this->size;
}

if ($this->sort) {
$body['sort'] = $this->sort->toDSL();
}

return [
$this->name => [
'top_hits' => empty($body) ? new stdClass() : $body,
],
];
}
}
30 changes: 30 additions & 0 deletions tests/IntegrationTests/AggregationQueryIntegrationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

use Ensi\LaravelElasticQuery\Aggregating\Bucket;
use Ensi\LaravelElasticQuery\Aggregating\Metrics\MinMaxScoreAggregation;
use Ensi\LaravelElasticQuery\Aggregating\Metrics\TopHitsAggregation;
use Ensi\LaravelElasticQuery\Aggregating\MinMax;
use Ensi\LaravelElasticQuery\Contracts\AggregationsBuilder;
use Ensi\LaravelElasticQuery\Search\Sorting\Sort;
Expand Down Expand Up @@ -53,6 +54,35 @@
);
});

test('aggregation query top hits', function () {
/** @var IntegrationTestCase $this */

$results = ProductsIndex::aggregate()
->terms(
name: 'group_by',
field: 'active',
composite: new TopHitsAggregation(
'top_products',
size: 10
)
)
->get();

$results = $results->get('group_by');

/** @var Bucket $result */
foreach ($results as $result) {
$groupByKey = $result->key;
/** @var array $products */
$products = $result->getCompositeValue('top_products');

array_walk($products, fn ($hit) => assertEquals($groupByKey, data_get($hit, '_source.active')));
$productIds = array_map(fn ($hit) => data_get($hit, '_source.product_id'), $products);

assertEqualsCanonicalizing($groupByKey ? [1, 150, 328, 405, 471] : [319], $productIds);
}
});

test('aggregation query cardinality', function () {
/** @var IntegrationTestCase $this */

Expand Down

0 comments on commit bf7a735

Please sign in to comment.