PHP code example of ashiqfardus / laravel-fuzzy-search
1. Go to this page and download the library: Download ashiqfardus/laravel-fuzzy-search library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
ashiqfardus / laravel-fuzzy-search example snippets
// Just add the trait and search!
use Ashiqfardus\LaravelFuzzySearch\Traits\Searchable;
class User extends Model
{
use Searchable;
}
// Search immediately - auto-detects searchable columns
$users = User::search('john')->get();
class User extends Model
{
use Searchable;
// Option 1: Define in $searchable property
protected array $searchable = [
'columns' => [
'name' => 10, // Highest priority
'email' => 5, // Medium priority
'bio' => 1, // Lowest priority
],
'algorithm' => 'fuzzy',
'typo_tolerance' => 2,
];
}
// Option 2: Specify at query time (merges with / adds to $searchable columns)
$users = User::search('john')
->searchIn(['name' => 10, 'email' => 5])
->get();
// Option 3: Simple array without weights (all get weight of 1)
$users = User::search('john')
->searchIn(['name', 'email', 'username'])
->get();
// Use specific algorithm
User::search('john')->using('levenshtein')->get();
User::search('stephen')->using('soundex')->get(); // Finds "Steven"
User::search('stephen')->using('metaphone')->get(); // More accurate phonetic — see setup below
User::search('laptop')->using('similar_text')->get(); // Percentage match
// database/migrations/{timestamp}_add_name_metaphone_to_users_table.php
Schema::table('users', function (Blueprint $table) {
$table->string('name_metaphone')->nullable()->after('name');
$table->index('name_metaphone');
});
// Auto typo tolerance based on word length
User::search('jonh')->get(); // Finds "John"
// Configure tolerance level
User::search('john')
->typoTolerance(1) // Allow 1 typo
->get();
// Disable typo tolerance
User::search('john')
->typoTolerance(0)
->get();
// Searches each word independently and combines results
User::search('john doe developer')
->tokenize() // Split into tokens
->matchAll() // All tokens must match (AND)
->get();
User::search('john doe developer')
->tokenize()
->matchAny() // Any token can match (OR)
->get();
use Ashiqfardus\LaravelFuzzySearch\Facades\FuzzySearch;
$matches = FuzzySearch::on($staticArray)->search('term')->searchIn(['name'])->get();
// Use default stop words
User::search('the quick brown fox')
->ignoreStopWords()
->get();
// Custom stop words
User::search('the quick brown fox')
->ignoreStopWords(['the', 'a', 'an', 'and', 'or', 'but'])
->get();
// Language-specific stop words
User::search('der schnelle braune fuchs')
->ignoreStopWords('de') // German stop words
->get();
User::search('laptop')
->withSynonyms([
'laptop' => ['notebook', 'computer', 'macbook'],
'phone' => ['mobile', 'cell', 'smartphone'],
])
->get();
// Or use synonym groups
User::search('laptop')
->synonymGroup(['laptop', 'notebook', 'computer'])
->get();
User::search('john')
->locale('en') // English
->get();
User::search('münchen')
->locale('de') // German - handles umlauts
->get();
// In config/fuzzy-search.php
'indexing' => [
'async' => true,
'queue' => 'search-indexing',
'chunk_size' => 500,
],
// Re-index a single model (dispatches IndexModelJob to queue)
use Ashiqfardus\LaravelFuzzySearch\Jobs\IndexModelJob;
IndexModelJob::dispatch(User::class, $user->id);
// Cache search results
User::search('john')
->cache(minutes: 60)
->get();
// Cache with custom key
User::search('john')
->cache(60, 'user-search-john')
->get();
// Use Redis for pattern storage
// In config/fuzzy-search.php
'cache' => [
'enabled' => true,
'driver' => 'redis',
'ttl' => 3600,
],
// config/fuzzy-search.php
'indexing' => [
'enabled' => true, // must be true or saves are never indexed
'async' => true, // true = queued (recommended for production)
'queue' => 'indexing', // dedicated queue keeps indexing isolated
'chunk_size' => 500,
'max_tokens_per_doc' => 5000, // security cap: prevents index poisoning
],
use Ashiqfardus\LaravelFuzzySearch\Traits\Searchable;
class User extends Model
{
use Searchable;
protected array $searchable = [
'columns' => [
'name' => 10,
'email' => 5,
'bio' => 2,
],
];
}
// BM25 search — faster + better relevance on large tables
$users = User::search('john')->useInvertedIndex()->get();
// didYouMean() reads from the term dictionary — O(1) at any dataset size
$suggestions = User::search('jonh')->searchIn(['name'])->didYouMean(3);
// In your test setUp
config(['fuzzy-search.indexing.enabled' => true, 'fuzzy-search.indexing.async' => false]);
// Exact first name + prefix last name + exclude banned
$users = User::search('=John ^Doe !banned')->extended()->get();
// OR semantics with grouping
$users = User::search('admin (john | jane)')->extended()->get();
// More examples
'Sr$ | Jr$' // Names ending in Sr OR Jr
"'manager [email protected]$" // Substring 'manager' but not @temp.com emails
use Laravel\Scout\Searchable;
use Ashiqfardus\LaravelFuzzySearch\Traits\Searchable as FuzzySearchable;
class User extends Model
{
use Searchable, FuzzySearchable {
// FuzzySearchable::search() takes precedence — returns the fluent SearchBuilder.
// Scout's underlying engine (FuzzySearchEngine) is still used when SCOUT_DRIVER=fuzzy-search.
FuzzySearchable::search insteadof Searchable;
Searchable::search as scoutSearch;
}
public function toSearchableArray(): array
{
return ['name' => $this->name, 'email' => $this->email];
}
}
$users = User::search('john')->get();
// Automatically falls back to simpler algorithm if primary fails
User::search('john')
->using('trigram')
->fallback('fuzzy') // First fallback
->fallback('simple') // Second fallback
->get();
// Use blog preset but with higher typo tolerance
Post::search('laravel')
->preset('blog')
->typoTolerance(3) // Override preset's default of 2
->get();