Skip to content

Commit d324e8f

Browse files
authored
Merge pull request #90 from ensi-platform/idbpr-2901-v7
IDBPR-2901 Add TopHits v7
2 parents 053fecb + 8fc648d commit d324e8f

File tree

2 files changed

+83
-0
lines changed

2 files changed

+83
-0
lines changed
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<?php
2+
3+
namespace Ensi\LaravelElasticQuery\Aggregating\Metrics;
4+
5+
use Ensi\LaravelElasticQuery\Contracts\Aggregation;
6+
use Ensi\LaravelElasticQuery\Search\Sorting\SortCollection;
7+
use stdClass;
8+
use Webmozart\Assert\Assert;
9+
10+
class TopHitsAggregation implements Aggregation
11+
{
12+
public function __construct(
13+
private string $name,
14+
private ?int $size = null,
15+
private array $source = [],
16+
private ?SortCollection $sort = null,
17+
) {
18+
Assert::stringNotEmpty(trim($name));
19+
Assert::nullOrGreaterThan($this->size, 0);
20+
}
21+
22+
public function name(): string
23+
{
24+
return $this->name;
25+
}
26+
27+
public function parseResults(array $response): array
28+
{
29+
return [$this->name => $response[$this->name]['hits']['hits'] ?? []];
30+
}
31+
32+
public function toDSL(): array
33+
{
34+
$body = [];
35+
36+
if ($this->size !== null) {
37+
$body['size'] = $this->size;
38+
}
39+
40+
if ($this->sort) {
41+
$body['sort'] = $this->sort->toDSL();
42+
}
43+
if (!empty($this->source)) {
44+
$body['_source'] = $this->source;
45+
}
46+
47+
return [
48+
$this->name => [
49+
'top_hits' => empty($body) ? new stdClass() : $body,
50+
],
51+
];
52+
}
53+
}

tests/IntegrationTests/AggregationQueryIntegrationTest.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
use Ensi\LaravelElasticQuery\Aggregating\Bucket;
44
use Ensi\LaravelElasticQuery\Aggregating\Metrics\MinMaxScoreAggregation;
5+
use Ensi\LaravelElasticQuery\Aggregating\Metrics\TopHitsAggregation;
56
use Ensi\LaravelElasticQuery\Aggregating\MinMax;
67
use Ensi\LaravelElasticQuery\Contracts\AggregationsBuilder;
78
use Ensi\LaravelElasticQuery\Search\Sorting\Sort;
@@ -53,6 +54,35 @@
5354
);
5455
});
5556

57+
test('aggregation query top hits', function () {
58+
/** @var IntegrationTestCase $this */
59+
60+
$results = ProductsIndex::aggregate()
61+
->terms(
62+
name: 'group_by',
63+
field: 'active',
64+
composite: new TopHitsAggregation(
65+
'top_products',
66+
size: 10
67+
)
68+
)
69+
->get();
70+
71+
$results = $results->get('group_by');
72+
73+
/** @var Bucket $result */
74+
foreach ($results as $result) {
75+
$groupByKey = $result->key;
76+
/** @var array $products */
77+
$products = $result->getCompositeValue('top_products');
78+
79+
array_walk($products, fn ($hit) => assertEquals($groupByKey, data_get($hit, '_source.active')));
80+
$productIds = array_map(fn ($hit) => data_get($hit, '_source.product_id'), $products);
81+
82+
assertEqualsCanonicalizing($groupByKey ? [1, 150, 328, 405, 471] : [319], $productIds);
83+
}
84+
});
85+
5686
test('aggregation query cardinality', function () {
5787
/** @var IntegrationTestCase $this */
5888

0 commit comments

Comments
 (0)