Skip to content

Commit f9ac29f

Browse files
Add highlight implementation for elasticsearch and opensearch adapter (#490)
1 parent 1afdfc9 commit f9ac29f

File tree

2 files changed

+94
-12
lines changed

2 files changed

+94
-12
lines changed

packages/seal-elasticsearch-adapter/src/ElasticsearchSearcher.php

+47-6
Original file line numberDiff line numberDiff line change
@@ -64,13 +64,13 @@ public function search(Search $search): Result
6464
}
6565

6666
return new Result(
67-
$this->hitsToDocuments($search->index, []),
67+
$this->hitsToDocuments($search->index, [], []),
6868
0,
6969
);
7070
}
7171

7272
return new Result(
73-
$this->hitsToDocuments($search->index, [$searchResult]),
73+
$this->hitsToDocuments($search->index, [$searchResult], []),
7474
1,
7575
);
7676
}
@@ -99,6 +99,20 @@ public function search(Search $search): Result
9999
$body['size'] = $search->limit;
100100
}
101101

102+
if ([] !== $search->highlightFields) {
103+
$highlightFields = [];
104+
foreach ($search->highlightFields as $highlightField) {
105+
$highlightFields[$highlightField] = [
106+
'pre_tags' => [$search->highlightPreTag],
107+
'post_tags' => [$search->highlightPostTag],
108+
];
109+
}
110+
111+
$body['highlight'] = [
112+
'fields' => $highlightFields,
113+
];
114+
}
115+
102116
/** @var Elasticsearch $response */
103117
$response = $this->client->search([
104118
'index' => $search->index->name,
@@ -118,21 +132,48 @@ public function search(Search $search): Result
118132
$searchResult = $response->asArray();
119133

120134
return new Result(
121-
$this->hitsToDocuments($search->index, $searchResult['hits']['hits']),
135+
$this->hitsToDocuments($search->index, $searchResult['hits']['hits'], $search->highlightFields),
122136
$searchResult['hits']['total']['value'],
123137
);
124138
}
125139

126140
/**
127141
* @param array<array<string, mixed>> $hits
142+
* @param array<string> $highlightFields
128143
*
129144
* @return \Generator<int, array<string, mixed>>
130145
*/
131-
private function hitsToDocuments(Index $index, array $hits): \Generator
146+
private function hitsToDocuments(Index $index, array $hits, array $highlightFields): \Generator
132147
{
133-
/** @var array{_index: string, _source: array<string, mixed>} $hit */
148+
/** @var array{_index: string, _source: array<string, mixed>, highlight?: mixed} $hit */
134149
foreach ($hits as $hit) {
135-
yield $this->marshaller->unmarshall($index->fields, $hit['_source']);
150+
$document = $this->marshaller->unmarshall($index->fields, $hit['_source']);
151+
152+
if ([] === $highlightFields) {
153+
yield $document;
154+
155+
continue;
156+
}
157+
158+
$document['_formatted'] ??= [];
159+
160+
\assert(
161+
\is_array($document['_formatted']),
162+
'Document with key "_formatted" expected to be array.',
163+
);
164+
165+
foreach ($highlightFields as $highlightField) {
166+
\assert(
167+
isset($hit['highlight'])
168+
&& \is_array($hit['highlight'])
169+
&& isset($hit['highlight'][$highlightField])
170+
&& \is_array($hit['highlight'][$highlightField]),
171+
);
172+
173+
$document['_formatted'][$highlightField] = $hit['highlight'][$highlightField][0] ?? null;
174+
}
175+
176+
yield $document;
136177
}
137178
}
138179

packages/seal-opensearch-adapter/src/OpensearchSearcher.php

+47-6
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,13 @@ public function search(Search $search): Result
5454
]);
5555
} catch (Missing404Exception) {
5656
return new Result(
57-
$this->hitsToDocuments($search->index, []),
57+
$this->hitsToDocuments($search->index, [], []),
5858
0,
5959
);
6060
}
6161

6262
return new Result(
63-
$this->hitsToDocuments($search->index, [$searchResult]),
63+
$this->hitsToDocuments($search->index, [$searchResult], []),
6464
1,
6565
);
6666
}
@@ -89,27 +89,68 @@ public function search(Search $search): Result
8989
$body['size'] = $search->limit;
9090
}
9191

92+
if ([] !== $search->highlightFields) {
93+
$highlightFields = [];
94+
foreach ($search->highlightFields as $highlightField) {
95+
$highlightFields[$highlightField] = [
96+
'pre_tags' => [$search->highlightPreTag],
97+
'post_tags' => [$search->highlightPostTag],
98+
];
99+
}
100+
101+
$body['highlight'] = [
102+
'fields' => $highlightFields,
103+
];
104+
}
105+
92106
$searchResult = $this->client->search([
93107
'index' => $search->index->name,
94108
'body' => $body,
95109
]);
96110

97111
return new Result(
98-
$this->hitsToDocuments($search->index, $searchResult['hits']['hits']),
112+
$this->hitsToDocuments($search->index, $searchResult['hits']['hits'], $search->highlightFields),
99113
$searchResult['hits']['total']['value'],
100114
);
101115
}
102116

103117
/**
104118
* @param array<array<string, mixed>> $hits
119+
* @param array<string> $highlightFields
105120
*
106121
* @return \Generator<int, array<string, mixed>>
107122
*/
108-
private function hitsToDocuments(Index $index, array $hits): \Generator
123+
private function hitsToDocuments(Index $index, array $hits, array $highlightFields): \Generator
109124
{
110-
/** @var array{_index: string, _source: array<string, mixed>} $hit */
125+
/** @var array{_index: string, _source: array<string, mixed>, highlight?: mixed} $hit */
111126
foreach ($hits as $hit) {
112-
yield $this->marshaller->unmarshall($index->fields, $hit['_source']);
127+
$document = $this->marshaller->unmarshall($index->fields, $hit['_source']);
128+
129+
if ([] === $highlightFields) {
130+
yield $document;
131+
132+
continue;
133+
}
134+
135+
$document['_formatted'] ??= [];
136+
137+
\assert(
138+
\is_array($document['_formatted']),
139+
'Document with key "_formatted" expected to be array.',
140+
);
141+
142+
foreach ($highlightFields as $highlightField) {
143+
\assert(
144+
isset($hit['highlight'])
145+
&& \is_array($hit['highlight'])
146+
&& isset($hit['highlight'][$highlightField])
147+
&& \is_array($hit['highlight'][$highlightField]),
148+
);
149+
150+
$document['_formatted'][$highlightField] = $hit['highlight'][$highlightField][0] ?? null;
151+
}
152+
153+
yield $document;
113154
}
114155
}
115156

0 commit comments

Comments
 (0)