This guide will help you get up and running with Laravel Fuzzy Search in just a few minutes.
- PHP 8.0 or higher
- Laravel 9.x, 10.x, 11.x, 12.x, or 13.x
- MySQL, PostgreSQL, SQLite, or SQL Server
composer require ashiqfardus/laravel-fuzzy-searchThat's it! The package is auto-discovered and ready to use immediately.
php artisan vendor:publish --tag=fuzzy-search-configThis creates config/fuzzy-search.php where you can customize default settings.
Add the Searchable trait to any Eloquent model:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Ashiqfardus\LaravelFuzzySearch\Traits\Searchable;
class Article extends Model
{
use Searchable;
}The package auto-detects common column names:
// Automatically searches: title, name, email, description, etc.
$articles = Article::search('laravel')->get();For better results, specify which columns to search:
class Article extends Model
{
use Searchable;
protected array $searchable = [
'columns' => [
'title' => 10, // Highest weight
'body' => 5, // Medium weight
'excerpt' => 3, // Lower weight
],
'algorithm' => 'fuzzy', // Default algorithm
'typo_tolerance' => 2, // Allow 2 character differences
];
}// Basic search
$results = Article::search('laravel')->get();
// With pagination
$results = Article::search('laravel')->paginate(20);
// Limit results
$results = Article::search('laravel')->take(10)->get();$results = Article::search('laravel')
->where('status', 'published')
->where('created_at', '>', now()->subDays(30))
->orderBy('created_at', 'desc')
->get();$results = Article::search('laravel')
->withRelevance()
->get();
foreach ($results as $article) {
echo "Score: " . $article->_score;
echo "Title: " . $article->title;
}$results = Article::search('laravel')
->highlight('mark') // Wraps matches in <mark> tags
->get();
foreach ($results as $article) {
echo $article->_highlighted['title'];
// Output: "Getting started with <mark>Laravel</mark> Fuzzy Search"
}class Post extends Model
{
use Searchable;
protected array $searchable = [
'columns' => [
'title' => 10,
'body' => 5,
'excerpt' => 3,
],
];
}
// Usage
$posts = Post::search('getting started with laravel')
->where('status', 'published')
->paginate(15);Or use the blog preset:
$posts = Post::search('getting started with laravel')
->preset('blog')
->paginate(15);class Product extends Model
{
use Searchable;
protected array $searchable = [
'columns' => [
'name' => 10,
'sku' => 8,
'brand' => 6,
'description' => 5,
],
'typo_tolerance' => 1, // Lower tolerance for SKUs
];
}
// Usage - handles typos automatically
$products = Product::search('iphone 15 pro') // Finds "iPhone 15 Pro"
->where('stock', '>', 0)
->orderBy('price', 'asc')
->get();Or use the ecommerce preset:
$products = Product::search('iphone 15 pro')
->preset('ecommerce')
->get();class User extends Model
{
use Searchable;
protected array $searchable = [
'columns' => [
'name' => 10,
'username' => 9,
'email' => 8,
],
];
}
// Usage - finds users with typo tolerance
$users = User::search('john') // Finds "John", "Jon", "Johnny"
->get();Or use the users preset:
$users = User::search('john')
->preset('users')
->get();Perfect for searching names that sound similar:
$users = User::search('steven')
->using('soundex') // Finds "Stephen", "Stefan", "Stephan"
->get();Or use the phonetic preset:
$users = User::search('steven')
->preset('phonetic')
->get();public function autocomplete(Request $request)
{
$query = $request->input('q');
$suggestions = Product::search($query)
->take(10)
->get(['name', 'sku', 'image']);
return response()->json($suggestions);
}With suggestions:
$suggestions = Product::search($query)
->suggest() // Returns suggested completions
->take(10);// Match ANY word (default)
$results = Article::search('laravel php framework')
->matchAny() // Finds articles with "laravel" OR "php" OR "framework"
->get();
// Match ALL words
$results = Article::search('laravel php framework')
->matchAll() // Only finds articles with all three words
->get();use Ashiqfardus\LaravelFuzzySearch\FederatedSearch;
$results = FederatedSearch::across([
Article::class,
Product::class,
User::class,
])
->search('laravel')
->get();
foreach ($results as $result) {
echo "Type: " . $result->_model_type;
echo "Score: " . $result->_score;
}$results = Article::search('laravel')
->scoreWith(function($article, $baseScore) {
// Boost recent articles
$recencyBoost = $article->created_at->gt(now()->subDays(7)) ? 20 : 0;
// Boost featured articles
$featuredBoost = $article->is_featured ? 50 : 0;
return $baseScore + $recencyBoost + $featuredBoost;
})
->get();$results = Article::search('the best laravel tutorial')
->ignoreStopWords(['the', 'a', 'an']) // Ignores "the"
->withSynonyms([
'tutorial' => ['guide', 'lesson', 'walkthrough']
])
->get();$results = Article::search('laravel')
->debugScore() // Shows score breakdown
->get();
foreach ($results as $article) {
print_r($article->_score_breakdown);
}
// Get debug info about search configuration
$debugInfo = Article::search('laravel')
->using('fuzzy')
->typoTolerance(2)
->getDebugInfo();
print_r($debugInfo);You can also use fuzzy search directly on query builders:
use Illuminate\Support\Facades\DB;
// Simple where clause
$results = DB::table('articles')
->whereFuzzy('title', 'laravel')
->get();
// Multiple columns
$results = DB::table('articles')
->whereFuzzyMultiple(['title', 'body'], 'laravel')
->get();Problem: Search returns empty results even though data exists.
Solutions:
- Check if columns are searchable:
// Make sure columns are fillable or specified in $searchable
protected $fillable = ['title', 'body'];- Lower typo tolerance temporarily:
$results = Article::search('test')
->typoTolerance(0) // Exact matches only
->get();- Use exact algorithm:
$results = Article::search('test')
->preset('exact')
->get();- Enable debug mode:
$results = Article::search('test')
->debugScore()
->get();Problem: EmptySearchTermException is thrown.
Solution: Either provide a search term or allow empty searches:
// Option 1: Check before searching
if (!empty($searchTerm)) {
$results = Article::search($searchTerm)->get();
} else {
$results = Article::all();
}
// Option 2: Enable in config
// config/fuzzy-search.php
'allow_empty_search' => true,Problem: Search queries are slow with large datasets.
Solutions:
- Enable search index:
// In config
'indexing' => [
'enabled' => true,
'async' => true,
],
// Build index
php artisan fuzzy-search:index Article- Enable caching:
$results = Article::search('laravel')
->cache(60) // Cache for 60 minutes
->get();- Reduce columns searched:
// Only search most important columns
$results = Article::search('laravel')
->searchIn(['title' => 10]) // Only search title
->get();- Use simple algorithm for large datasets:
$results = Article::search('laravel')
->using('simple') // Faster but less typo-tolerant
->get();Problem: InvalidAlgorithmException is thrown.
Solution: Use a valid algorithm:
// Valid algorithms: fuzzy, levenshtein, soundex, trigram, simple
$results = Article::search('test')
->using('fuzzy') // ✓ Valid
->get();- Read the full documentation
- Check out performance tips
- Learn about algorithm comparison
- View API reference
- Browse example implementations