Skip to content

Commit 2398386

Browse files
committed
✨ Introduce fuzzy search
1 parent 5b8dc6e commit 2398386

File tree

3 files changed

+72
-2
lines changed

3 files changed

+72
-2
lines changed

README.md

+21
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,27 @@ $games = Game::search('Fortnite')->get();
120120

121121
**Attention:** Searchable models are `Character`, `Collection`, `Game`, `Platform` and `Theme`.
122122

123+
#### Fuzzy Search ("where like" chain) (since v3.1.0)
124+
125+
```php
126+
use MarcReichel\IGDBLaravel\Models\Game;
127+
128+
$games = Game::fuzzySearch(
129+
// fields to search in
130+
[
131+
'name',
132+
'involved_companies.company.name', // you can search for nested values as well
133+
],
134+
// the query to search for
135+
'Call of Duty',
136+
// enable/disable case sensitivity (disabled by default)
137+
false,
138+
)->get();
139+
```
140+
141+
**Attention**: Keep in mind you have to do the sorting of the results yourself. They are not ordered by relevance or
142+
something like this.
143+
123144
#### Where-Clauses
124145

125146
##### Simple Where Clauses

src/Builder.php

+49-2
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,53 @@ public function search(string $query): self
226226
return $this;
227227
}
228228

229+
/**
230+
* Add a fuzzy search to the query.
231+
*
232+
* @param mixed $key
233+
* @param string $query
234+
* @param bool $caseSensitive
235+
* @param string $boolean
236+
*
237+
* @return self
238+
* @throws ReflectionException
239+
*/
240+
public function fuzzySearch(
241+
mixed $key,
242+
string $query,
243+
bool $caseSensitive = false,
244+
string $boolean = '&',
245+
): self {
246+
$tokenizedQuery = explode(' ', $query);
247+
$keys = collect($key)->crossJoin($tokenizedQuery)->toArray();
248+
249+
return $this->whereNested(function ($query) use ($keys, $caseSensitive) {
250+
foreach($keys as $v) {
251+
$query->whereLike($v[0], $v[1], $caseSensitive, '|');
252+
}
253+
}, $boolean);
254+
}
255+
256+
/**
257+
* Add an "or fuzzy search" to the query.
258+
*
259+
* @param mixed $key
260+
* @param string $query
261+
* @param bool $caseSensitive
262+
* @param string $boolean
263+
*
264+
* @return self
265+
* @throws ReflectionException
266+
*/
267+
public function orFuzzySearch(
268+
mixed $key,
269+
string $query,
270+
bool $caseSensitive = false,
271+
string $boolean = '|',
272+
): self {
273+
return $this->fuzzySearch($key, $query, $caseSensitive, $boolean);
274+
}
275+
229276
/**
230277
* Add a basic where clause to the query.
231278
*
@@ -431,8 +478,8 @@ private function generateWhereLikeClause($key, $value, $caseSensitive, $operator
431478
}
432479

433480
$operator = $caseSensitive ? $operator : $insensitiveOperator;
434-
$prefix = $hasPrefix ? '*' : '';
435-
$suffix = $hasSuffix ? '*' : '';
481+
$prefix = $hasPrefix || !$hasSuffix ? '*' : '';
482+
$suffix = $hasSuffix || !$hasPrefix ? '*' : '';
436483
$value = json_encode($value, JSON_THROW_ON_ERROR);
437484
$value = Str::start(Str::finish($value, $suffix), $prefix);
438485

src/Models/Model.php

+2
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030
* @method static Builder skip(int $limit)
3131
* @method static Builder forPage(int $page, int $perPage = 10)
3232
* @method static Builder search(string $query)
33+
* @method static Builder fuzzySearch(mixed $key, string $query, bool $caseSensitive = false, string $boolean = '&')
34+
* @method static Builder orFuzzySearch(mixed $key, string $query, bool $caseSensitive = false, string $boolean = '|')
3335
* @method static Builder where(mixed $key, mixed|null $operator = null, mixed|null $value = null, string $boolean = '&')
3436
* @method static Builder orWhere(mixed $key, mixed|null $operator = null, mixed|null $value = null, string $boolean = '|')
3537
* @method static Builder whereLike(string $key, string $value, bool $caseSensitive = true, string $boolean = '&')

0 commit comments

Comments
 (0)