Skip to content

Commit 9ce1816

Browse files
Spamerczclaude
andcommitted
feat(query): add field masking span query
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent a4015e2 commit 9ce1816

3 files changed

Lines changed: 117 additions & 0 deletions

File tree

doc/02-query-objects.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -695,6 +695,19 @@ new \Spameri\ElasticQuery\Query\SpanMulti(
695695
);
696696
```
697697

698+
##### FieldMaskingSpan Query
699+
Mask a span clause to act on a different field — enables span queries across multiple fields.
700+
- Class: `\Spameri\ElasticQuery\Query\FieldMaskingSpan`
701+
- [Documentation](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-span-field-masking-query.html)
702+
- [Implementation](https://github.com/Spameri/ElasticQuery/blob/master/src/Query/FieldMaskingSpan.php)
703+
704+
```php
705+
new \Spameri\ElasticQuery\Query\FieldMaskingSpan(
706+
query: new \Spameri\ElasticQuery\Query\SpanTerm('text.stems', 'fox'),
707+
field: 'text',
708+
);
709+
```
710+
698711
##### SpanTerm Query
699712
Match a single term in a span-aware way.
700713
- Class: `\Spameri\ElasticQuery\Query\SpanTerm`

src/Query/FieldMaskingSpan.php

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
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-span-field-masking-query.html
9+
*/
10+
class FieldMaskingSpan implements \Spameri\ElasticQuery\Query\LeafQueryInterface
11+
{
12+
13+
public function __construct(
14+
private \Spameri\ElasticQuery\Query\LeafQueryInterface $query,
15+
private string $field,
16+
)
17+
{
18+
}
19+
20+
21+
public function key(): string
22+
{
23+
return 'field_masking_span_' . $this->field . '_' . $this->query->key();
24+
}
25+
26+
27+
/**
28+
* @return array<string, array<string, mixed>>
29+
*/
30+
public function toArray(): array
31+
{
32+
return [
33+
'field_masking_span' => [
34+
'query' => $this->query->toArray(),
35+
'field' => $this->field,
36+
],
37+
];
38+
}
39+
40+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace SpameriTests\ElasticQuery\Query;
4+
5+
require_once __DIR__ . '/../../bootstrap.php';
6+
7+
8+
class FieldMaskingSpan extends \Tester\TestCase
9+
{
10+
11+
private const INDEX = 'spameri_test_query_field_masking_span';
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+
$span = new \Spameri\ElasticQuery\Query\FieldMaskingSpan(
29+
query: new \Spameri\ElasticQuery\Query\SpanTerm('text.stems', 'fox'),
30+
field: 'text',
31+
);
32+
33+
$array = $span->toArray();
34+
35+
\Tester\Assert::same('text', $array['field_masking_span']['field']);
36+
\Tester\Assert::true(isset($array['field_masking_span']['query']['span_term']));
37+
}
38+
39+
40+
public function testKey(): void
41+
{
42+
$span = new \Spameri\ElasticQuery\Query\FieldMaskingSpan(
43+
new \Spameri\ElasticQuery\Query\SpanTerm('text.stems', 'fox'),
44+
'text',
45+
);
46+
47+
\Tester\Assert::same('field_masking_span_text_span_term_text.stems_fox', $span->key());
48+
}
49+
50+
51+
public function tearDown(): void
52+
{
53+
$ch = \curl_init();
54+
\curl_setopt($ch, \CURLOPT_URL, \ELASTICSEARCH_HOST . '/' . self::INDEX);
55+
\curl_setopt($ch, \CURLOPT_RETURNTRANSFER, 1);
56+
\curl_setopt($ch, \CURLOPT_CUSTOMREQUEST, 'DELETE');
57+
\curl_setopt($ch, \CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
58+
59+
\curl_exec($ch);
60+
}
61+
62+
}
63+
64+
(new FieldMaskingSpan())->run();

0 commit comments

Comments
 (0)