eslam-dev/laravel-searchable
Composer 安装命令:
composer require eslam-dev/laravel-searchable
包简介
Laravel Searchable — dedicated searchable columns for Eloquent with cleaning, FULLTEXT search, and rebuild tooling
README 文档
README
A Laravel package for dedicated searchable text columns on Eloquent models: automatic fill on save, text cleaning, and MySQL FULLTEXT search.
Features
✅ Migration Macros - Simple searchableColumn() macro for creating LONGTEXT columns with FULLTEXT indexes
✅ Automatic Population - Searchable columns are automatically updated on model save
✅ Text Cleaning - Comprehensive text normalization (HTML stripping, Arabic normalization, diacritic removal)
✅ FULLTEXT Search - Native MySQL FULLTEXT search with natural language mode
✅ Multiple Columns - Support for multiple searchable columns per model
✅ Relationship Support - Extract text from relationships using dot notation
✅ Translatable Fields - Automatic extraction from JSON/translatable fields
✅ Queue Support - Rebuild searchable columns via queue for large datasets
✅ Highly Configurable - Customize cleaning rules, separators, and extraction methods
Requirements
- PHP 8.2+
- Laravel 12.0+
- MySQL 5.6+ or MariaDB 10.0+
Installation
Install via Composer:
composer require eslam-dev/laravel-searchable
Publish the configuration file:
php artisan vendor:publish --tag=laravel-searchable-config
Quick Start
1. Add Searchable Columns to Migration
use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; Schema::create('products', function (Blueprint $table) { $table->id(); $table->json('title'); $table->json('description'); $table->string('sku'); // Add searchable columns with automatic FULLTEXT index $table->searchableColumn('title_search'); $table->searchableColumn('description_search'); $table->searchableColumn('combined_search'); $table->timestamps(); });
2. Add Trait to Model
use Illuminate\Database\Eloquent\Model; use EslamDev\SearchableColumns\Traits\HasSearchableColumns; class Product extends Model { use HasSearchableColumns; protected array $searchableColumns = [ // Simple: one source field 'title_search' => ['title'], // Multiple source fields 'description_search' => ['description', 'short_description'], // Combined search across multiple fields 'combined_search' => ['title', 'description', 'sku'], ]; }
3. Search Your Data
// Search across all defined searchable columns $products = Product::search('iphone 13 pro')->get(); // Search specific column $products = Product::searchIn('title_search', 'iphone')->get(); // Search multiple columns $products = Product::searchIn(['title_search', 'description_search'], 'phone')->get(); // Combine with other filters $products = Product::search('laptop') ->where('status', 'published') ->inStock() ->get();
Advanced Usage
Relationship Fields
Extract text from related models:
protected array $searchableColumns = [ 'search_text' => [ 'title', 'description', 'brand.name', // BelongsTo relationship 'categories.*.name', // BelongsToMany/HasMany ], ];
Translatable Fields
For models using Spatie's Translatable or JSON fields:
protected array $searchableColumns = [ 'search_text' => [ 'sources' => ['title', 'description', 'brand.name'], 'extract_translations' => 'all', // 'all', 'default', or false 'separator' => ' | ', ], ];
Options:
'all'- Combines all translations: "Phone هاتف"'default'- Uses only the default localefalse- Treats as regular string
Custom Cleaning Rules
Override cleaning rules per model:
protected array $searchableCleaningRules = [ 'strip_html' => true, 'decode_entities' => true, 'normalize_arabic' => true, 'remove_diacritics' => true, 'lowercase' => true, 'remove_symbols' => false, // Keep symbols 'collapse_whitespace' => true, ];
LIKE Fallback
For cases where FULLTEXT isn't suitable:
// Force LIKE search $products = Product::searchLike('title_search', 'partial')->get(); // Search multiple columns with LIKE $products = Product::searchLike(['title_search', 'description_search'], 'text')->get();
Artisan Commands
Rebuild Searchable Columns
Rebuild searchable columns for existing records:
# Rebuild all models php artisan searchable:rebuild # Specific model php artisan searchable:rebuild --model="App\Models\Product" # With progress bar php artisan searchable:rebuild --model="App\Models\Product" --verbose # Queue processing for large datasets php artisan searchable:rebuild --model="App\Models\Product" --queue # Specific queue php artisan searchable:rebuild --model="App\Models\Product" --queue --queue-name=search-rebuild
Configuration
The configuration file config/laravel-searchable.php provides extensive customization options:
return [ // Enable/disable FULLTEXT indexes 'enable_fulltext' => true, // Default text cleaning rules 'cleaning_rules' => [ 'strip_html' => true, 'decode_entities' => true, 'normalize_arabic' => true, 'remove_diacritics' => true, 'lowercase' => true, 'remove_symbols' => true, 'collapse_whitespace' => true, ], // Arabic normalization mappings 'arabic_normalizations' => [ 'أ' => 'ا', 'إ' => 'ا', 'آ' => 'ا', 'ة' => 'ه', 'ى' => 'ي', ], // Translation extraction mode 'extract_translations' => 'all', // 'all', 'default', or false // Queue settings 'queue' => 'default', 'chunk_size' => 500, // ... and more ];
Text Cleaning Pipeline
The package applies a comprehensive cleaning pipeline:
- Strip HTML - Removes all HTML tags
- Decode Entities - Converts HTML entities (
&→&) - Normalize Arabic - Standardizes Arabic character variants
- Remove Diacritics - Strips Arabic tashkeel marks
- Convert to Lowercase - Standardizes case for better matching
- Remove Symbols - Strips punctuation and special characters
- Collapse Whitespace - Normalizes spacing
Performance Optimization
MySQL Configuration
For better Arabic search, configure MySQL:
# /etc/mysql/my.cnf [mysqld] ft_min_word_length = 3
Then rebuild the FULLTEXT index:
OPTIMIZE TABLE products;
Queue Processing
For large datasets, use queue processing:
php artisan searchable:rebuild --model="App\Models\Product" --queue
Configure chunk size in config/laravel-searchable.php:
'chunk_size' => 500, // Adjust based on your needs
Eager Loading
The package automatically eager loads relationships used in searchable columns to prevent N+1 queries.
Testing
The package includes comprehensive unit and feature tests:
composer test
Test Requirements
Tests require a MySQL database. Configure in phpunit.xml:
<env name="DB_CONNECTION" value="mysql"/> <env name="DB_DATABASE" value="searchable_test"/> <env name="DB_USERNAME" value="root"/> <env name="DB_PASSWORD" value=""/>
Examples
E-commerce Product Search
class Product extends Model { use HasSearchableColumns, HasTranslations; public $translatable = ['title', 'description']; protected array $searchableColumns = [ 'search_text' => [ 'title', 'description', 'sku', 'barcode', 'brand.name', 'categories.*.name', ], ]; } // Search usage $results = Product::search('iphone 13 pro') ->published() ->inStock() ->get();
Multi-language Content
class Article extends Model { use HasSearchableColumns, HasTranslations; public $translatable = ['title', 'content']; protected array $searchableColumns = [ 'search_text' => [ 'sources' => ['title', 'content', 'author.name'], 'extract_translations' => 'all', // Index all languages ], ]; } // Searches in both English and Arabic $results = Article::search('tutorial')->get();
Selective Searchable Columns
class Post extends Model { use HasSearchableColumns; protected array $searchableColumns = [ 'title_search' => ['title'], 'content_search' => ['content', 'excerpt'], 'full_search' => ['title', 'content', 'excerpt', 'tags.*.name'], ]; } // Search only titles Post::searchIn('title_search', 'laravel')->get(); // Search content Post::searchIn('content_search', 'tutorial')->get(); // Full search Post::search('laravel tutorial')->get();
Troubleshooting
FULLTEXT Search Not Working
- Ensure you're using MySQL 5.6+ or MariaDB 10.0+
- Check that FULLTEXT indexes are created:
SHOW INDEX FROM products WHERE Key_name LIKE '%search%';
- Verify minimum word length matches your content:
SHOW VARIABLES LIKE 'ft_min_word_length';
Arabic Search Issues
- Set
ft_min_word_length = 3in MySQL configuration - Rebuild FULLTEXT indexes:
OPTIMIZE TABLE products; - Verify Arabic normalization is enabled in config
Performance Issues
- Use queue processing for bulk rebuilds
- Adjust chunk size in configuration
- Add database indexes on frequently filtered columns
- Consider using Laravel Scout for more advanced search needs
Security
If you discover any security-related issues, please open a private security advisory on the repository instead of using the public issue tracker.
License
The MIT License (MIT). Please see License File for more information.
Credits
- eslam-dev
- All Contributors
Support
- 🐛 Issues: GitHub Issues
- 📖 Documentation: Full Documentation
eslam-dev/laravel-searchable 适用场景与选型建议
eslam-dev/laravel-searchable 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 74 次下载、GitHub Stars 达 0, 最近一次更新时间为 2026 年 05 月 02 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「search」 「mysql」 「laravel」 「fulltext」 「eloquent」 「searchable」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 eslam-dev/laravel-searchable 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 eslam-dev/laravel-searchable 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 eslam-dev/laravel-searchable 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
Dibi is Database Abstraction Library for PHP
A Laravel package to retrieve data from Google Search Console
Indexed Search Autocomplete - Extends the TYPO3 Core Extension Indexed_Search searchform with an autocomplete feature.
Abstraction Layer to index and search entities
Pimcore 10.x Website Indexer (powered by Zend Search Lucene)
Symfony bundle for Elasticsearch integration with round-robin load balancing
统计信息
- 总下载量: 74
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 19
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2026-05-02