From f5e8172daa08ffedd2c494195da0b1c04622f719 Mon Sep 17 00:00:00 2001 From: Olek Kaim Date: Sat, 26 Aug 2023 21:23:24 +0200 Subject: [PATCH] 1.10.0 release --- src/Builder/Builder.php | 37 +++++++- src/Contracts/BuilderInterface.php | 5 ++ tests/Unit/BuilderTest.php | 133 +++++++++++++++++++++++++++++ 3 files changed, 173 insertions(+), 2 deletions(-) diff --git a/src/Builder/Builder.php b/src/Builder/Builder.php index 942a0ff..4c10f03 100644 --- a/src/Builder/Builder.php +++ b/src/Builder/Builder.php @@ -2,6 +2,7 @@ namespace Olekjs\Elasticsearch\Builder; +use Closure; use Illuminate\Support\Traits\Conditionable; use LogicException; use Olekjs\Elasticsearch\Client; @@ -55,7 +56,9 @@ class Builder implements BuilderInterface private array $body = []; - public function __construct(private readonly ClientInterface $client) + private array $nested = []; + + public function __construct(private readonly ClientInterface $client = new Client()) { } @@ -174,6 +177,21 @@ public function whereRange(string $field, int|float $value, string $operator): s return $this; } + public function whereNested(string $path, Closure $closure): self + { + /** @var BuilderInterface $builder */ + $builder = $closure(new self()); + + $this->nested[] = [ + 'nested' => [ + 'path' => $path, + 'query' => $builder->getQuery(), + ] + ]; + + return $this; + } + /** * @throws LogicException */ @@ -423,10 +441,25 @@ public function getSelect(): array return $this->select; } + public function getNested(): array + { + return $this->nested; + } + public function performSearchBody(): void { + if (isset($this->nested)) { + foreach ($this->nested as $nested) { + $this->body['query']['bool']['must'][] = $nested; + } + } + if (isset($this->query)) { - $this->body['query'] = $this->query; + if (isset($this->nested)) { + $this->body['query']['bool']['must'][] = $this->query; + } else { + $this->body['query'] = $this->query; + } } if (isset($this->select)) { diff --git a/src/Contracts/BuilderInterface.php b/src/Contracts/BuilderInterface.php index 094221b..e881499 100644 --- a/src/Contracts/BuilderInterface.php +++ b/src/Contracts/BuilderInterface.php @@ -2,6 +2,7 @@ namespace Olekjs\Elasticsearch\Contracts; +use Closure; use LogicException; use Olekjs\Elasticsearch\Builder\Builder; use Olekjs\Elasticsearch\Dto\BulkResponseDto; @@ -55,6 +56,8 @@ public function whereBetween(string $field, array $values): self; public function whereRange(string $field, int|float $value, string $operator): self; + public function whereNested(string $path, Closure $closure): self; + /** * @throws LogicException */ @@ -142,5 +145,7 @@ public function getSort(): array; public function getSelect(): array; + public function getNested(): array; + public function performSearchBody(): void; } diff --git a/tests/Unit/BuilderTest.php b/tests/Unit/BuilderTest.php index 52abc85..4a96cb8 100644 --- a/tests/Unit/BuilderTest.php +++ b/tests/Unit/BuilderTest.php @@ -7,6 +7,7 @@ use Olekjs\Elasticsearch\Builder\Builder; use Olekjs\Elasticsearch\Bulk\Bulk; use Olekjs\Elasticsearch\Client; +use Olekjs\Elasticsearch\Contracts\BuilderInterface; use Olekjs\Elasticsearch\Dto\BulkResponseDto; use Olekjs\Elasticsearch\Dto\FindResponseDto; use Olekjs\Elasticsearch\Dto\IndexResponseDto; @@ -605,4 +606,136 @@ public function testWithAggregationMethod(): void $builder->getBody() ); } + + /** + * @dataProvider whereNestedDataProvider + */ + public function testWhereNestedMethod(\Closure $builder, array $actual): void + { + $expected = $builder(); + + $this->assertSame($expected, $actual); + } + + public static function whereNestedDataProvider(): iterable + { + yield [ + function () { + $builder = Builder::query(); + + $builder->whereNested('nested_path', function (BuilderInterface $builder) { + return $builder->whereIn('test', [1, 2, 3]); + }); + + $builder->performSearchBody(); + + return $builder->getBody(); + }, + [ + 'query' => [ + 'bool' => [ + 'must' => [ + [ + 'nested' => [ + 'path' => 'nested_path', + 'query' => [ + 'bool' => ['filter' => [['terms' => ['test' => [1, 2, 3]]]]] + ] + ] + ] + ] + ] + ] + ], + ]; + yield [ + function () { + $builder = Builder::query(); + + $builder->whereNested('nested_path', function (BuilderInterface $builder) { + return $builder + ->where('test', 1) + ->where('test_2', 2); + }); + + $builder->performSearchBody(); + + return $builder->getBody(); + }, + [ + 'query' => [ + 'bool' => [ + 'must' => [ + [ + 'nested' => [ + 'path' => 'nested_path', + 'query' => [ + 'bool' => [ + 'filter' => [ + ['term' => ['test' => 1]], + ['term' => ['test_2' => 2]], + ] + ] + ] + ] + ] + ] + ] + ] + ], + ]; + yield [ + function () { + $builder = Builder::query(); + + $builder->where('test_1', 1); + + $builder->whereNested('nested_path', function (BuilderInterface $builder) { + return $builder->where('test_2', 2); + }); + + $builder->where('test_3', 3); + + $builder->performSearchBody(); + + return $builder->getBody(); + }, + [ + 'query' => [ + 'bool' => [ + 'must' => [ + [ + 'nested' => [ + 'path' => 'nested_path', + 'query' => [ + 'bool' => [ + 'filter' => [ + ['term' => ['test_2' => 2]], + ] + ] + ] + ] + ], + [ + 'bool' => [ + 'filter' => [ + [ + 'term' => [ + 'test_1' => 1, + ] + ], + [ + 'term' => [ + 'test_3' => 3, + ] + ] + ] + ] + ] + ] + ] + ] + ], + ]; + } }