Skip to content

Commit bb279e6

Browse files
Add highlight methods to search and search builder (#348)
1 parent 3dd038f commit bb279e6

File tree

3 files changed

+99
-0
lines changed

3 files changed

+99
-0
lines changed

packages/seal/src/Search/Search.php

+4
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,17 @@ final class Search
2020
/**
2121
* @param object[] $filters
2222
* @param array<string, 'asc'|'desc'> $sortBys
23+
* @param array<string> $highlightFields
2324
*/
2425
public function __construct(
2526
public readonly Index $index,
2627
public readonly array $filters = [],
2728
public readonly array $sortBys = [],
2829
public readonly int|null $limit = null,
2930
public readonly int $offset = 0,
31+
public readonly array $highlightFields = [],
32+
public readonly string $highlightPreTag = '<mark>',
33+
public readonly string $highlightPostTag = '</mark>',
3034
) {
3135
}
3236
}

packages/seal/src/Search/SearchBuilder.php

+29
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,15 @@ final class SearchBuilder
3535

3636
private int|null $limit = null;
3737

38+
/**
39+
* @var array<string>
40+
*/
41+
private array $highlightFields = [];
42+
43+
private string $highlightPreTag = '<mark>';
44+
45+
private string $highlightPostTag = '</mark>';
46+
3847
public function __construct(
3948
readonly private Schema $schema,
4049
readonly private SearcherInterface $searcher,
@@ -79,6 +88,23 @@ public function offset(int $offset): static
7988
return $this;
8089
}
8190

91+
/**
92+
* @param array<string> $fields
93+
*/
94+
public function highlight(array $fields, string $preTag = '<mark>', string $postTag = '</mark>'): static
95+
{
96+
$this->highlightFields = $fields;
97+
$this->highlightPreTag = $preTag;
98+
$this->highlightPostTag = $postTag;
99+
100+
return $this;
101+
}
102+
103+
public function getSearcher(): SearcherInterface
104+
{
105+
return $this->searcher;
106+
}
107+
82108
public function getSearch(): Search
83109
{
84110
return new Search(
@@ -87,6 +113,9 @@ public function getSearch(): Search
87113
$this->sortBys,
88114
$this->limit,
89115
$this->offset,
116+
$this->highlightFields,
117+
$this->highlightPreTag,
118+
$this->highlightPostTag,
90119
);
91120
}
92121

packages/seal/src/Testing/AbstractSearcherTestCase.php

+66
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,72 @@ public function testSearchCondition(): void
131131
}
132132
}
133133

134+
public function testSearchConditionWithHighlight(): void
135+
{
136+
$documents = TestingHelper::createComplexFixtures();
137+
138+
$schema = self::getSchema();
139+
140+
foreach ($documents as $document) {
141+
self::$taskHelper->tasks[] = self::$indexer->save(
142+
$schema->indexes[TestingHelper::INDEX_COMPLEX],
143+
$document,
144+
['return_slow_promise_result' => true],
145+
);
146+
}
147+
self::$taskHelper->waitForAll();
148+
149+
$search = new SearchBuilder($schema, self::$searcher);
150+
$search->index(TestingHelper::INDEX_COMPLEX);
151+
$search->addFilter(new Condition\SearchCondition('Blog'));
152+
$search->highlight(['title'], '<mark>', '</mark>');
153+
154+
$expectedDocumentA = $documents[0];
155+
$expectedDocumentA['_formatted']['title'] = \str_replace(
156+
'Blog',
157+
'<mark>Blog</mark>',
158+
$expectedDocumentA['title'] ?? '',
159+
);
160+
$expectedDocumentB = $documents[1];
161+
$expectedDocumentB['_formatted']['title'] = \str_replace(
162+
'Blog',
163+
'<mark>Blog</mark>',
164+
$expectedDocumentB['title'] ?? '',
165+
);
166+
167+
$expectedDocumentsVariantA = [
168+
$expectedDocumentA,
169+
$expectedDocumentB,
170+
];
171+
$expectedDocumentsVariantB = [
172+
$expectedDocumentB,
173+
$expectedDocumentA,
174+
];
175+
176+
$loadedDocuments = [...$search->getResult()];
177+
$this->assertCount(2, $loadedDocuments);
178+
179+
$this->assertTrue(
180+
$expectedDocumentsVariantA === $loadedDocuments
181+
|| $expectedDocumentsVariantB === $loadedDocuments,
182+
'Not correct documents where found.',
183+
);
184+
185+
$search = new SearchBuilder($schema, self::$searcher);
186+
$search->index(TestingHelper::INDEX_COMPLEX);
187+
$search->addFilter(new Condition\SearchCondition('Thing'));
188+
189+
$this->assertSame([$documents[2]], [...$search->getResult()]);
190+
191+
foreach ($documents as $document) {
192+
self::$taskHelper->tasks[] = self::$indexer->delete(
193+
$schema->indexes[TestingHelper::INDEX_COMPLEX],
194+
$document['uuid'],
195+
['return_slow_promise_result' => true],
196+
);
197+
}
198+
}
199+
134200
public function testNoneSearchableFields(): void
135201
{
136202
$documents = TestingHelper::createComplexFixtures();

0 commit comments

Comments
 (0)