Skip to content

Commit adb9f10

Browse files
Merge pull request #13 from ginkelsoft-development/fix/elasticsearch-query-scopes
Fix/elasticsearch query scopes
2 parents 6975c73 + 1fea34f commit adb9f10

File tree

1 file changed

+61
-0
lines changed

1 file changed

+61
-0
lines changed

src/Traits/HasEncryptedSearchIndex.php

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,13 @@ public function scopeEncryptedExact(Builder $query, string $field, string $term)
221221

222222
$token = Tokens::exact($normalized, $pepper);
223223

224+
// Check if Elasticsearch is enabled
225+
if (config('encrypted-search.elasticsearch.enabled', false)) {
226+
$modelIds = $this->searchElasticsearch($field, $token, 'exact');
227+
return $query->whereIn($this->getQualifiedKeyName(), $modelIds);
228+
}
229+
230+
// Fallback to database
224231
return $query->whereIn($this->getQualifiedKeyName(), function ($sub) use ($field, $token) {
225232
$sub->select('model_id')
226233
->from('encrypted_search_index')
@@ -254,6 +261,13 @@ public function scopeEncryptedPrefix(Builder $query, string $field, string $term
254261
$pepper
255262
);
256263

264+
// Check if Elasticsearch is enabled
265+
if (config('encrypted-search.elasticsearch.enabled', false)) {
266+
$modelIds = $this->searchElasticsearch($field, $tokens, 'prefix');
267+
return $query->whereIn($this->getQualifiedKeyName(), $modelIds);
268+
}
269+
270+
// Fallback to database
257271
return $query->whereIn($this->getQualifiedKeyName(), function ($sub) use ($field, $tokens) {
258272
$sub->select('model_id')
259273
->from('encrypted_search_index')
@@ -264,6 +278,53 @@ public function scopeEncryptedPrefix(Builder $query, string $field, string $term
264278
});
265279
}
266280

281+
/**
282+
* Search for model IDs in Elasticsearch based on token(s).
283+
*
284+
* @param string $field
285+
* @param string|array<int, string> $tokens Single token or array of tokens
286+
* @param string $type Either 'exact' or 'prefix'
287+
* @return array<int, mixed> Array of model IDs
288+
*/
289+
protected function searchElasticsearch(string $field, $tokens, string $type): array
290+
{
291+
$index = config('encrypted-search.elasticsearch.index', 'encrypted_search');
292+
$service = app(ElasticsearchService::class);
293+
294+
// Normalize tokens to array
295+
$tokenArray = is_array($tokens) ? $tokens : [$tokens];
296+
297+
// Build Elasticsearch query
298+
$query = [
299+
'query' => [
300+
'bool' => [
301+
'must' => [
302+
['term' => ['model_type.keyword' => static::class]],
303+
['term' => ['field.keyword' => $field]],
304+
['term' => ['type.keyword' => $type]],
305+
['terms' => ['token.keyword' => $tokenArray]],
306+
],
307+
],
308+
],
309+
'_source' => ['model_id'],
310+
'size' => 10000,
311+
];
312+
313+
try {
314+
$results = $service->search($index, $query);
315+
316+
// Extract unique model IDs from results
317+
return collect($results)
318+
->pluck('_source.model_id')
319+
->unique()
320+
->values()
321+
->toArray();
322+
} catch (\Throwable $e) {
323+
logger()->warning('[EncryptedSearch] Elasticsearch search failed: ' . $e->getMessage());
324+
return [];
325+
}
326+
}
327+
267328
/**
268329
* Resolve the encrypted search configuration for this model.
269330
*

0 commit comments

Comments
 (0)