Skip to content

Commit 94266a7

Browse files
Spamerczclaude
andcommitted
feat(query): add parent id joining query
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 0369e28 commit 94266a7

3 files changed

Lines changed: 115 additions & 0 deletions

File tree

doc/02-query-objects.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,16 @@ new \Spameri\ElasticQuery\Query\Boosting(
344344

345345
Queries that traverse parent/child or join relationships.
346346

347+
##### ParentId Query
348+
Match children that belong to a parent with a known id.
349+
- Class: `\Spameri\ElasticQuery\Query\ParentId`
350+
- [Documentation](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-parent-id-query.html)
351+
- [Implementation](https://github.com/Spameri/ElasticQuery/blob/master/src/Query/ParentId.php)
352+
353+
```php
354+
new \Spameri\ElasticQuery\Query\ParentId(type: 'comment', id: '1');
355+
```
356+
347357
##### HasParent Query
348358
Match children whose parent matches the inner query.
349359
- Class: `\Spameri\ElasticQuery\Query\HasParent`

src/Query/ParentId.php

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?php
2+
3+
declare(strict_types = 1);
4+
5+
namespace Spameri\ElasticQuery\Query;
6+
7+
/**
8+
* @see https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-parent-id-query.html
9+
*/
10+
class ParentId implements \Spameri\ElasticQuery\Query\LeafQueryInterface
11+
{
12+
13+
public function __construct(
14+
private string $type,
15+
private string $id,
16+
private bool|null $ignoreUnmapped = null,
17+
)
18+
{
19+
}
20+
21+
22+
public function key(): string
23+
{
24+
return 'parent_id_' . $this->type . '_' . $this->id;
25+
}
26+
27+
28+
/**
29+
* @return array<string, array<string, mixed>>
30+
*/
31+
public function toArray(): array
32+
{
33+
$body = [
34+
'type' => $this->type,
35+
'id' => $this->id,
36+
];
37+
38+
if ($this->ignoreUnmapped !== null) {
39+
$body['ignore_unmapped'] = $this->ignoreUnmapped;
40+
}
41+
42+
return [
43+
'parent_id' => $body,
44+
];
45+
}
46+
47+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace SpameriTests\ElasticQuery\Query;
4+
5+
require_once __DIR__ . '/../../bootstrap.php';
6+
7+
8+
class ParentId extends \Tester\TestCase
9+
{
10+
11+
private const INDEX = 'spameri_test_query_parent_id';
12+
13+
14+
public function setUp(): void
15+
{
16+
$ch = \curl_init();
17+
\curl_setopt($ch, \CURLOPT_URL, \ELASTICSEARCH_HOST . '/' . self::INDEX);
18+
\curl_setopt($ch, \CURLOPT_RETURNTRANSFER, 1);
19+
\curl_setopt($ch, \CURLOPT_CUSTOMREQUEST, 'PUT');
20+
\curl_setopt($ch, \CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
21+
22+
\curl_exec($ch);
23+
}
24+
25+
26+
public function testToArray(): void
27+
{
28+
$parentId = new \Spameri\ElasticQuery\Query\ParentId(type: 'comment', id: '1');
29+
30+
$array = $parentId->toArray();
31+
32+
\Tester\Assert::same('comment', $array['parent_id']['type']);
33+
\Tester\Assert::same('1', $array['parent_id']['id']);
34+
}
35+
36+
37+
public function testKey(): void
38+
{
39+
$parentId = new \Spameri\ElasticQuery\Query\ParentId('comment', '1');
40+
41+
\Tester\Assert::same('parent_id_comment_1', $parentId->key());
42+
}
43+
44+
45+
public function tearDown(): void
46+
{
47+
$ch = \curl_init();
48+
\curl_setopt($ch, \CURLOPT_URL, \ELASTICSEARCH_HOST . '/' . self::INDEX);
49+
\curl_setopt($ch, \CURLOPT_RETURNTRANSFER, 1);
50+
\curl_setopt($ch, \CURLOPT_CUSTOMREQUEST, 'DELETE');
51+
\curl_setopt($ch, \CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
52+
53+
\curl_exec($ch);
54+
}
55+
56+
}
57+
58+
(new ParentId())->run();

0 commit comments

Comments
 (0)