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
5 changes: 4 additions & 1 deletion src/Aggregating/Bucket/FiltersAggregation.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,20 @@

namespace Ensi\LaravelElasticQuery\Aggregating\Bucket;

use Ensi\LaravelElasticQuery\Aggregating\AggregationCollection;
use Ensi\LaravelElasticQuery\Aggregating\BucketCollection;
use Ensi\LaravelElasticQuery\Aggregating\FiltersCollection;
use Ensi\LaravelElasticQuery\Aggregating\Result;
use Ensi\LaravelElasticQuery\Contracts\Aggregation;
use Illuminate\Support\Collection;
use Webmozart\Assert\Assert;

class FiltersAggregation implements Aggregation
{
public function __construct(
private string $name,
private FiltersCollection $filters,
private ?Aggregation $composite = null,
private Aggregation|AggregationCollection|null $composite = null,
private ?string $otherBucketKey = null,
) {
Assert::stringNotEmpty(trim($name));
Expand Down Expand Up @@ -45,6 +47,7 @@ public function parseResults(array $response): array
$buckets = array_map(
function (mixed $key, array $bucket) {
$values = $this->isComposite() ? $this->composite->parseResults($bucket) : [];
$values = $values instanceof Collection ? $values->toArray() : $values;

return Result::parseBucketWithKey($key, $bucket, $values);
},
Expand Down
8 changes: 6 additions & 2 deletions src/Aggregating/Bucket/TermsAggregation.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@

namespace Ensi\LaravelElasticQuery\Aggregating\Bucket;

use Ensi\LaravelElasticQuery\Aggregating\AggregationCollection;
use Ensi\LaravelElasticQuery\Aggregating\BucketCollection;
use Ensi\LaravelElasticQuery\Aggregating\Result;
use Ensi\LaravelElasticQuery\Contracts\Aggregation;
use Ensi\LaravelElasticQuery\Search\Sorting\Sort;
use Ensi\LaravelElasticQuery\Search\Sorting\SortCollection;
use Illuminate\Support\Collection;
use Webmozart\Assert\Assert;

class TermsAggregation implements Aggregation
Expand All @@ -14,8 +17,8 @@ public function __construct(
private string $name,
private string $field,
private ?int $size = null,
private ?Sort $sort = null,
private ?Aggregation $composite = null,
private Sort|SortCollection|null $sort = null,
private Aggregation|AggregationCollection|null $composite = null,
) {
Assert::stringNotEmpty(trim($name));
Assert::stringNotEmpty(trim($field));
Expand Down Expand Up @@ -57,6 +60,7 @@ public function parseResults(array $response): array
$buckets = array_map(
function (array $bucket) {
$values = $this->isComposite() ? $this->composite->parseResults($bucket) : [];
$values = $values instanceof Collection ? $values->toArray() : $values;

return Result::parseBucket($bucket, $values);
},
Expand Down
42 changes: 42 additions & 0 deletions src/Aggregating/Metrics/MaxAggregation.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php

namespace Ensi\LaravelElasticQuery\Aggregating\Metrics;

use Ensi\LaravelElasticQuery\Aggregating\Result;
use Ensi\LaravelElasticQuery\Contracts\Aggregation;
use Webmozart\Assert\Assert;

class MaxAggregation implements Aggregation
{
public function __construct(
private readonly string $name,
private readonly string $field,
private readonly mixed $missing = null,
) {
Assert::stringNotEmpty(trim($name));
Assert::stringNotEmpty(trim($field));
}

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

public function toDSL(): array
{
$body['field'] = $this->field;

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

return [
$this->name => ['max' => $body],
];
}

public function parseResults(array $response): array
{
return [$this->name => Result::parseValue($response[$this->name]) ?? 0];
}
}
42 changes: 42 additions & 0 deletions src/Aggregating/Metrics/MinAggregation.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php

namespace Ensi\LaravelElasticQuery\Aggregating\Metrics;

use Ensi\LaravelElasticQuery\Aggregating\Result;
use Ensi\LaravelElasticQuery\Contracts\Aggregation;
use Webmozart\Assert\Assert;

class MinAggregation implements Aggregation
{
public function __construct(
private readonly string $name,
private readonly string $field,
private readonly mixed $missing = null,
) {
Assert::stringNotEmpty(trim($name));
Assert::stringNotEmpty(trim($field));
}

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

public function toDSL(): array
{
$body['field'] = $this->field;

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

return [
$this->name => ['min' => $body],
];
}

public function parseResults(array $response): array
{
return [$this->name => Result::parseValue($response[$this->name]) ?? 0];
}
}
23 changes: 20 additions & 3 deletions src/Concerns/ConstructsAggregations.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,15 @@
use Ensi\LaravelElasticQuery\Aggregating\CompositeAggregationBuilder;
use Ensi\LaravelElasticQuery\Aggregating\FiltersCollection;
use Ensi\LaravelElasticQuery\Aggregating\Metrics\CardinalityAggregation;
use Ensi\LaravelElasticQuery\Aggregating\Metrics\MaxAggregation;
use Ensi\LaravelElasticQuery\Aggregating\Metrics\MinAggregation;
use Ensi\LaravelElasticQuery\Aggregating\Metrics\MinMaxAggregation;
use Ensi\LaravelElasticQuery\Aggregating\Metrics\ValueCountAggregation;
use Ensi\LaravelElasticQuery\Contracts\Aggregation;
use Ensi\LaravelElasticQuery\Contracts\Criteria;
use Ensi\LaravelElasticQuery\Filtering\BoolQueryBuilder;
use Ensi\LaravelElasticQuery\Search\Sorting\Sort;
use Ensi\LaravelElasticQuery\Search\Sorting\SortCollection;

trait ConstructsAggregations
{
Expand All @@ -30,8 +33,8 @@ public function terms(
string $name,
string $field,
?int $size = null,
?Sort $sort = null,
?Aggregation $composite = null,
Sort|SortCollection|null $sort = null,
Aggregation|AggregationCollection|null $composite = null,
): static {
$this->aggregations->add(new TermsAggregation($name, $this->absolutePath($field), $size, $sort, $composite));

Expand All @@ -48,7 +51,7 @@ public function filter(string $name, Criteria $criteria, AggregationCollection $
public function filters(
string $name,
FiltersCollection $filters,
?Aggregation $composite = null,
Aggregation|AggregationCollection|null $composite = null,
?string $otherBucketKey = null,
): static {
$this->aggregations->add(new FiltersAggregation($name, $filters, $composite, $otherBucketKey));
Expand All @@ -63,6 +66,20 @@ public function minmax(string $name, string $field): static
return $this;
}

public function min(string $name, string $field, mixed $missing = null): static
{
$this->aggregations->add(new MinAggregation($name, $this->absolutePath($field), $missing));

return $this;
}

public function max(string $name, string $field, mixed $missing = null): static
{
$this->aggregations->add(new MaxAggregation($name, $this->absolutePath($field), $missing));

return $this;
}

public function count(string $name, string $field): static
{
$this->aggregations->add(new ValueCountAggregation($name, $this->absolutePath($field)));
Expand Down
4 changes: 4 additions & 0 deletions src/Contracts/AggregationsBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ public function terms(string $name, string $field, ?int $size = null): static;

public function minmax(string $name, string $field): static;

public function min(string $name, string $field, mixed $missing = null): static;

public function max(string $name, string $field, mixed $missing = null): static;

public function count(string $path, string $field): static;

public function nested(string $path, Closure $callback): static;
Expand Down
9 changes: 8 additions & 1 deletion tests/IntegrationTests/AggregationQueryIntegrationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,11 @@
->count('product_count', 'product_id')
->nested(
'offers',
fn (AggregationsBuilder $builder) => $builder->where('seller_id', 10)->minmax('price', 'price')
fn (AggregationsBuilder $builder) => $builder
->where('seller_id', 10)
->minmax('price', 'price')
->min('min_price', 'price')
->max('max_price', 'price')
)
->get();

Expand All @@ -38,6 +42,9 @@
);

assertEquals(new MinMax(168.0, 611.0), $results->get('price'));
assertEquals(168.0, $results->get('min_price'));
assertEquals(611.0, $results->get('max_price'));

assertEquals(2, $results->get('product_count'));
});

Expand Down