diszo2009/zendsearch
Laravel-friendly integration of ZendSearch for full-text indexing and search. Provides a simple way to configure and use ZendSearch in PHP apps, helping you add fast text search capabilities with minimal setup.
Installation
composer require diszo2009/zendsearch
Ensure ext-zendsearch PHP extension is enabled in php.ini.
Basic Usage
Initialize the ZendSearch engine in a service provider (e.g., AppServiceProvider):
use Diszo2009\ZendSearch\ZendSearch;
public function register()
{
$this->app->singleton('zendsearch', function ($app) {
return new ZendSearch($app['config']['zendsearch.path']);
});
}
First Use Case: Indexing Documents
$zendSearch = app('zendsearch');
$zendSearch->addDocument('doc1', ['title' => 'Laravel', 'content' => 'A PHP framework...']);
$zendSearch->commit();
Searching
$results = $zendSearch->search('framework', ['fields' => ['title', 'content']]);
Indexing Workflow
foreach (Post::all() as $post) {
$zendSearch->addDocument("post_{$post->id}", [
'title' => $post->title,
'content' => $post->body,
]);
}
$zendSearch->commit();
updateDocument() for modified records.Search Integration
Route::get('/search', function () {
$query = request('q');
$results = app('zendsearch')->search($query);
return response()->json($results);
});
// In a trait or service
public function scopeSearch($query, $searchTerm)
{
$results = app('zendsearch')->search($searchTerm);
return $query->whereIn('id', array_map(fn($r) => $r['id'], $results));
}
Hybrid Search Combine with database queries for relevance tuning:
$zendResults = app('zendsearch')->search($query, ['sort' => 'rank']);
$dbResults = Post::whereIn('id', array_column($zendResults, 'id'))->get();
config/zendsearch.php:
return [
'path' => storage_path('app/zendsearch'),
];
event(new SearchPerformed($query, $results));
$cacheKey = "search_{$query}";
$results = cache()->remember($cacheKey, now()->addHours(1), function () use ($query) {
return app('zendsearch')->search($query);
});
Path Permissions
config['zendsearch.path']) is writable:
chmod -R 775 storage/app/zendsearch
Memory Limits
memory_limit. Increase it temporarily:
ini_set('memory_limit', '512M');
addDocument() in chunks for massive datasets.Case Sensitivity
$query = strtolower(request('q'));
Field Mapping
$zendSearch->addDocument('doc1', ['title' => 'Test', 'exclude' => 'field']);
$docs = $zendSearch->getDocuments();
ZendSearchException:
try {
$zendSearch->search('invalid_query');
} catch (\Exception $e) {
Log::error($e->getMessage());
}
Custom Scoring Override the default ranking logic by extending the class:
class CustomZendSearch extends \Diszo2009\ZendSearch\ZendSearch {
public function search($query, $options = []) {
$results = parent::search($query, $options);
// Custom scoring logic here
return $results;
}
}
Plugin System Add pre/post hooks for indexing/searching:
$zendSearch->on('beforeSearch', function ($query) {
// Modify query or log
});
Async Indexing Use Laravel Queues to offload indexing:
Post::find($id)->dispatch(new IndexPostJob($id));
// In IndexPostJob
public function handle() {
$post = Post::find($this->postId);
app('zendsearch')->addDocument("post_{$post->id}", [...]);
app('zendsearch')->commit();
}
Multi-Index Support Maintain separate indexes for different data types:
$blogIndex = new ZendSearch(storage_path('app/blog_index'));
$productIndex = new ZendSearch(storage_path('app/product_index'));
How can I help you explore Laravel packages today?