Skip to content

Commit 9151647

Browse files
authored
Merge pull request #13 from olekjs/1.10.0
1.10.0 release
2 parents 9b84c7d + f5e8172 commit 9151647

File tree

3 files changed

+173
-2
lines changed

3 files changed

+173
-2
lines changed

src/Builder/Builder.php

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

33
namespace Olekjs\Elasticsearch\Builder;
44

5+
use Closure;
56
use Illuminate\Support\Traits\Conditionable;
67
use LogicException;
78
use Olekjs\Elasticsearch\Client;
@@ -55,7 +56,9 @@ class Builder implements BuilderInterface
5556

5657
private array $body = [];
5758

58-
public function __construct(private readonly ClientInterface $client)
59+
private array $nested = [];
60+
61+
public function __construct(private readonly ClientInterface $client = new Client())
5962
{
6063
}
6164

@@ -174,6 +177,21 @@ public function whereRange(string $field, int|float $value, string $operator): s
174177
return $this;
175178
}
176179

180+
public function whereNested(string $path, Closure $closure): self
181+
{
182+
/** @var BuilderInterface $builder */
183+
$builder = $closure(new self());
184+
185+
$this->nested[] = [
186+
'nested' => [
187+
'path' => $path,
188+
'query' => $builder->getQuery(),
189+
]
190+
];
191+
192+
return $this;
193+
}
194+
177195
/**
178196
* @throws LogicException
179197
*/
@@ -423,10 +441,25 @@ public function getSelect(): array
423441
return $this->select;
424442
}
425443

444+
public function getNested(): array
445+
{
446+
return $this->nested;
447+
}
448+
426449
public function performSearchBody(): void
427450
{
451+
if (isset($this->nested)) {
452+
foreach ($this->nested as $nested) {
453+
$this->body['query']['bool']['must'][] = $nested;
454+
}
455+
}
456+
428457
if (isset($this->query)) {
429-
$this->body['query'] = $this->query;
458+
if (isset($this->nested)) {
459+
$this->body['query']['bool']['must'][] = $this->query;
460+
} else {
461+
$this->body['query'] = $this->query;
462+
}
430463
}
431464

432465
if (isset($this->select)) {

src/Contracts/BuilderInterface.php

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

33
namespace Olekjs\Elasticsearch\Contracts;
44

5+
use Closure;
56
use LogicException;
67
use Olekjs\Elasticsearch\Builder\Builder;
78
use Olekjs\Elasticsearch\Dto\BulkResponseDto;
@@ -55,6 +56,8 @@ public function whereBetween(string $field, array $values): self;
5556

5657
public function whereRange(string $field, int|float $value, string $operator): self;
5758

59+
public function whereNested(string $path, Closure $closure): self;
60+
5861
/**
5962
* @throws LogicException
6063
*/
@@ -142,5 +145,7 @@ public function getSort(): array;
142145

143146
public function getSelect(): array;
144147

148+
public function getNested(): array;
149+
145150
public function performSearchBody(): void;
146151
}

tests/Unit/BuilderTest.php

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use Olekjs\Elasticsearch\Builder\Builder;
88
use Olekjs\Elasticsearch\Bulk\Bulk;
99
use Olekjs\Elasticsearch\Client;
10+
use Olekjs\Elasticsearch\Contracts\BuilderInterface;
1011
use Olekjs\Elasticsearch\Dto\BulkResponseDto;
1112
use Olekjs\Elasticsearch\Dto\FindResponseDto;
1213
use Olekjs\Elasticsearch\Dto\IndexResponseDto;
@@ -605,4 +606,136 @@ public function testWithAggregationMethod(): void
605606
$builder->getBody()
606607
);
607608
}
609+
610+
/**
611+
* @dataProvider whereNestedDataProvider
612+
*/
613+
public function testWhereNestedMethod(\Closure $builder, array $actual): void
614+
{
615+
$expected = $builder();
616+
617+
$this->assertSame($expected, $actual);
618+
}
619+
620+
public static function whereNestedDataProvider(): iterable
621+
{
622+
yield [
623+
function () {
624+
$builder = Builder::query();
625+
626+
$builder->whereNested('nested_path', function (BuilderInterface $builder) {
627+
return $builder->whereIn('test', [1, 2, 3]);
628+
});
629+
630+
$builder->performSearchBody();
631+
632+
return $builder->getBody();
633+
},
634+
[
635+
'query' => [
636+
'bool' => [
637+
'must' => [
638+
[
639+
'nested' => [
640+
'path' => 'nested_path',
641+
'query' => [
642+
'bool' => ['filter' => [['terms' => ['test' => [1, 2, 3]]]]]
643+
]
644+
]
645+
]
646+
]
647+
]
648+
]
649+
],
650+
];
651+
yield [
652+
function () {
653+
$builder = Builder::query();
654+
655+
$builder->whereNested('nested_path', function (BuilderInterface $builder) {
656+
return $builder
657+
->where('test', 1)
658+
->where('test_2', 2);
659+
});
660+
661+
$builder->performSearchBody();
662+
663+
return $builder->getBody();
664+
},
665+
[
666+
'query' => [
667+
'bool' => [
668+
'must' => [
669+
[
670+
'nested' => [
671+
'path' => 'nested_path',
672+
'query' => [
673+
'bool' => [
674+
'filter' => [
675+
['term' => ['test' => 1]],
676+
['term' => ['test_2' => 2]],
677+
]
678+
]
679+
]
680+
]
681+
]
682+
]
683+
]
684+
]
685+
],
686+
];
687+
yield [
688+
function () {
689+
$builder = Builder::query();
690+
691+
$builder->where('test_1', 1);
692+
693+
$builder->whereNested('nested_path', function (BuilderInterface $builder) {
694+
return $builder->where('test_2', 2);
695+
});
696+
697+
$builder->where('test_3', 3);
698+
699+
$builder->performSearchBody();
700+
701+
return $builder->getBody();
702+
},
703+
[
704+
'query' => [
705+
'bool' => [
706+
'must' => [
707+
[
708+
'nested' => [
709+
'path' => 'nested_path',
710+
'query' => [
711+
'bool' => [
712+
'filter' => [
713+
['term' => ['test_2' => 2]],
714+
]
715+
]
716+
]
717+
]
718+
],
719+
[
720+
'bool' => [
721+
'filter' => [
722+
[
723+
'term' => [
724+
'test_1' => 1,
725+
]
726+
],
727+
[
728+
'term' => [
729+
'test_3' => 3,
730+
]
731+
]
732+
]
733+
]
734+
]
735+
]
736+
]
737+
]
738+
],
739+
];
740+
}
608741
}

0 commit comments

Comments
 (0)