Skip to content

Commit 4d9899a

Browse files
committed
Expand search response objects
1 parent 49c478f commit 4d9899a

14 files changed

Lines changed: 536 additions & 31 deletions

src/Search/Bucket.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,19 @@ public function __construct(
1717
) {}
1818

1919
/**
20-
* Get the number of documents in the bucket.
20+
* Get the bucket key.
2121
*/
22-
public function docCount(): int
22+
public function key(): mixed
2323
{
24-
return $this->bucket['doc_count'] ?? 0;
24+
return $this->bucket['key'];
2525
}
2626

2727
/**
28-
* Get the bucket key.
28+
* Get the number of documents in the bucket.
2929
*/
30-
public function key(): mixed
30+
public function docCount(): int
3131
{
32-
return $this->bucket['key'];
32+
return $this->bucket['doc_count'] ?? 0;
3333
}
3434

3535
/**

src/Search/Hit.php

Lines changed: 69 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ public function __construct(
2121
/**
2222
* Get the index name for the hit.
2323
*/
24-
public function indexName(): string
24+
public function index(): string
2525
{
2626
return $this->hit['_index'];
2727
}
@@ -34,24 +34,82 @@ public function score(): ?float
3434
return $this->hit['_score'];
3535
}
3636

37+
/**
38+
* Get the document identifier for the hit.
39+
*/
40+
public function id(): string
41+
{
42+
return $this->hit['_id'];
43+
}
44+
45+
/**
46+
* Get the document source for the hit.
47+
*
48+
* @return array<string, mixed>
49+
*/
50+
public function source(): array
51+
{
52+
return $this->hit['_source'] ?? [];
53+
}
54+
3755
/**
3856
* Get the document for the hit.
3957
*/
4058
public function document(): Document
4159
{
42-
return new Document(
43-
$this->hit['_id'],
44-
$this->hit['_source'] ?? []
45-
);
60+
return new Document($this->id(), $this->source());
61+
}
62+
63+
/**
64+
* Get the returned document fields.
65+
*
66+
* @return array<string, mixed>
67+
*/
68+
public function fields(): array
69+
{
70+
return $this->hit['fields'] ?? [];
71+
}
72+
73+
/**
74+
* Get the hit sort values.
75+
*
76+
* @return array<int, mixed>
77+
*/
78+
public function sort(): array
79+
{
80+
return $this->hit['sort'] ?? [];
81+
}
82+
83+
/**
84+
* Get the matched query names.
85+
*
86+
* @return array<int, string>
87+
*/
88+
public function matchedQueries(): array
89+
{
90+
return $this->hit['matched_queries'] ?? [];
91+
}
92+
93+
/**
94+
* Get the score explanation.
95+
*
96+
* @return array<string, mixed>|null
97+
*/
98+
public function explanation(): ?array
99+
{
100+
return $this->hit['_explanation'] ?? null;
46101
}
47102

48103
/**
49104
* Get the highlight for the hit.
50105
*/
51106
public function highlight(): ?Highlight
52107
{
53-
return isset($this->hit['highlight']) ?
54-
new Highlight($this->hit['highlight']) : null;
108+
if (isset($this->hit['highlight'])) {
109+
return new Highlight($this->hit['highlight']);
110+
}
111+
112+
return null;
55113
}
56114

57115
/**
@@ -61,15 +119,10 @@ public function highlight(): ?Highlight
61119
*/
62120
public function innerHits(): array
63121
{
64-
$innerHits = $this->hit['inner_hits'] ?? [];
65-
66-
return array_map(
67-
static fn (array $hits) => array_map(
68-
static fn (array $hit) => new self($hit),
69-
$hits['hits']['hits'],
70-
),
71-
$innerHits,
72-
);
122+
return array_map(fn (array $hits) => array_map(
123+
fn (array $hit) => new self($hit),
124+
$hits['hits']['hits'],
125+
), $this->hit['inner_hits'] ?? []);
73126
}
74127

75128
/**

src/Search/SearchRequest.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@ class SearchRequest
1717
/**
1818
* Create a new search request instance.
1919
*
20-
* @param array<string, mixed>|null $query
20+
* @param array<string, mixed> $query
2121
*/
22-
public function __construct(?array $query = null)
22+
public function __construct(array $query = [])
2323
{
24-
if (isset($query)) {
24+
if (! empty($query)) {
2525
$this->request['body']['query'] = $query;
2626
}
2727
}

src/Search/SearchResponse.php

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,48 @@ public function hits(): array
2828
return array_map(static fn (array $hit) => new Hit($hit), $hits);
2929
}
3030

31+
/**
32+
* Get the search execution time in milliseconds.
33+
*/
34+
public function took(): ?int
35+
{
36+
return $this->response['took'] ?? null;
37+
}
38+
39+
/**
40+
* Determine if the search timed out.
41+
*/
42+
public function timedOut(): bool
43+
{
44+
return $this->response['timed_out'] ?? false;
45+
}
46+
47+
/**
48+
* Get the search shard statistics.
49+
*/
50+
public function shards(): ?ShardStatistics
51+
{
52+
return isset($this->response['_shards'])
53+
? new ShardStatistics($this->response['_shards'])
54+
: null;
55+
}
56+
57+
/**
58+
* Get the total hit count metadata.
59+
*/
60+
public function totalHits(): ?TotalHits
61+
{
62+
return isset($this->response['hits']['total'])
63+
? new TotalHits($this->response['hits']['total'])
64+
: null;
65+
}
66+
3167
/**
3268
* Get the total number of matching documents.
3369
*/
3470
public function total(): ?int
3571
{
36-
return $this->response['hits']['total']['value'] ?? null;
72+
return $this->totalHits()?->value();
3773
}
3874

3975
/**

src/Search/ShardStatistics.php

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
<?php
2+
3+
namespace DirectoryTree\OpenSearchAdapter\Search;
4+
5+
/**
6+
* @see https://docs.opensearch.org/latest/api-reference/search-apis/search/
7+
*/
8+
class ShardStatistics implements RawResponseInterface
9+
{
10+
/**
11+
* Create a new shard statistics instance.
12+
*
13+
* @param array<string, mixed> $shards
14+
*/
15+
public function __construct(
16+
protected array $shards,
17+
) {}
18+
19+
/**
20+
* Get the total number of shards searched.
21+
*/
22+
public function total(): int
23+
{
24+
return $this->shards['total'];
25+
}
26+
27+
/**
28+
* Get the number of shards that searched successfully.
29+
*/
30+
public function successful(): int
31+
{
32+
return $this->shards['successful'];
33+
}
34+
35+
/**
36+
* Get the number of shards skipped during the search.
37+
*/
38+
public function skipped(): int
39+
{
40+
return $this->shards['skipped'] ?? 0;
41+
}
42+
43+
/**
44+
* Get the number of shards that failed during the search.
45+
*/
46+
public function failed(): int
47+
{
48+
return $this->shards['failed'];
49+
}
50+
51+
/**
52+
* Get the shard failures.
53+
*
54+
* @return array<int, array<string, mixed>>
55+
*/
56+
public function failures(): array
57+
{
58+
return $this->shards['failures'] ?? [];
59+
}
60+
61+
/**
62+
* Get the raw OpenSearch shard statistics payload.
63+
*
64+
* @return array<string, mixed>
65+
*/
66+
public function raw(): array
67+
{
68+
return $this->shards;
69+
}
70+
}

src/Search/Suggestion.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,14 @@ public function length(): int
4343
/**
4444
* Get the suggestion options.
4545
*
46-
* @return array<int, array<string, mixed>>
46+
* @return array<int, SuggestionOption>
4747
*/
4848
public function options(): array
4949
{
50-
return $this->suggestion['options'];
50+
return array_map(
51+
static fn (array $option) => new SuggestionOption($option),
52+
$this->suggestion['options'],
53+
);
5154
}
5255

5356
/**

src/Search/SuggestionOption.php

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
<?php
2+
3+
namespace DirectoryTree\OpenSearchAdapter\Search;
4+
5+
/**
6+
* @see https://docs.opensearch.org/latest/search-plugins/searching-data/did-you-mean/
7+
*/
8+
class SuggestionOption implements RawResponseInterface
9+
{
10+
/**
11+
* Create a new suggestion option instance.
12+
*
13+
* @param array<string, mixed> $option
14+
*/
15+
public function __construct(
16+
protected array $option,
17+
) {}
18+
19+
/**
20+
* Get the suggestion option text.
21+
*/
22+
public function text(): string
23+
{
24+
return $this->option['text'];
25+
}
26+
27+
/**
28+
* Get the suggestion option score.
29+
*/
30+
public function score(): ?float
31+
{
32+
return $this->option['score'] ?? null;
33+
}
34+
35+
/**
36+
* Get the highlighted suggestion option text.
37+
*/
38+
public function highlighted(): ?string
39+
{
40+
return $this->option['highlighted'] ?? null;
41+
}
42+
43+
/**
44+
* Determine if the collate query matched for the suggestion option.
45+
*/
46+
public function collateMatch(): ?bool
47+
{
48+
return $this->option['collate_match'] ?? null;
49+
}
50+
51+
/**
52+
* Get the document source for completion suggestion options.
53+
*
54+
* @return array<string, mixed>|null
55+
*/
56+
public function source(): ?array
57+
{
58+
return $this->option['_source'] ?? null;
59+
}
60+
61+
/**
62+
* Get the raw OpenSearch suggestion option payload.
63+
*
64+
* @return array<string, mixed>
65+
*/
66+
public function raw(): array
67+
{
68+
return $this->option;
69+
}
70+
}

0 commit comments

Comments
 (0)