Installation:
composer require babenkoivan/elastic-client
Publish the config file:
php artisan vendor:publish --provider="Babenkoivan\ElasticClient\ElasticClientServiceProvider" --tag="config"
Configuration:
Edit config/elastic.php to match your Elasticsearch cluster settings:
'connections' => [
'default' => [
'hosts' => ['http://localhost:9200'],
'username' => env('ELASTIC_USERNAME'),
'password' => env('ELASTIC_PASSWORD'),
],
],
First Use Case:
Index a model (e.g., Post) in AppServiceProvider@boot():
use Babenkoivan\ElasticClient\ElasticClient;
public function boot()
{
ElasticClient::index('posts', Post::class);
}
Basic Query:
$results = ElasticClient::search('posts', [
'query' => [
'match' => ['title' => 'Laravel']
]
]);
ElasticClient::index() in a service provider to sync models to Elasticsearch.$casts to define Elasticsearch field types:
protected $casts = [
'published_at' => 'date',
'is_active' => 'boolean',
];
ElasticClient::search('posts', [
'query' => ['match' => ['content' => 'search term']]
]);
ElasticClient::search('posts', [
'aggs' => [
'tags' => ['terms' => ['field' => 'tags.keyword']]
]
]);
ElasticClient::search('posts', [
'from' => 0,
'size' => 10,
'query' => [...]
]);
ElasticClient::bulkIndex('posts', Post::all()->toArray());
ElasticClient::update('posts', $postId, ['title' => 'Updated Title']);
AppServiceProvider for dependency injection:
$this->app->singleton(ElasticClient::class, function ($app) {
return new ElasticClient(config('elastic.connections.default'));
});
use Babenkoivan\ElasticClient\Query\Builder;
$results = Builder::for('posts')
->where('title', 'like', 'Laravel')
->paginate(10);
Define analyzers in config/elastic.php:
'analyzers' => [
'custom_analyzer' => [
'type' => 'custom',
'tokenizer' => 'standard',
'filter' => ['lowercase', 'asciifolding']
],
],
Apply to a field in your model:
ElasticClient::index('posts', Post::class, [
'properties' => [
'title' => [
'type' => 'text',
'analyzer' => 'custom_analyzer'
]
]
]);
Listen for model events to sync changes:
Post::saved(function ($post) {
ElasticClient::update('posts', $post->id, $post->toArray());
});
Use connection switching for tenant-specific indices:
ElasticClient::connection('tenant_' . $tenantId)->search('posts', [...]);
Cache frequent queries using Laravel's cache:
$cacheKey = 'elastic_posts_' . md5(serialize($query));
return Cache::remember($cacheKey, now()->addHours(1), function () use ($query) {
return ElasticClient::search('posts', $query);
});
Mapping Conflicts:
?ignore=400 in the connection config to suppress mapping errors during updates.Bulk Operations:
?refresh=wait_for to control indexing delays.Connection Issues:
config/elastic.php:
'log' => [
'enabled' => true,
'level' => 'debug',
],
Field Type Mismatches:
$casts may not align with Elasticsearch types (e.g., string vs. text).ElasticClient::index().Rate Limiting:
scroll API for large datasets:
$scroll = ElasticClient::scroll('posts', '1m', 1000);
Raw Responses: Access raw Elasticsearch responses for debugging:
$response = ElasticClient::raw('posts/_search', ['body' => $query]);
Explain Queries:
Use _explain to debug relevance scores:
ElasticClient::explain('posts', $postId, [
'query' => ['match' => ['content' => 'search term']]
]);
Profile Queries: Enable profiling in queries:
ElasticClient::search('posts', [
'profile' => true,
'query' => [...]
]);
Custom Clients: Extend the base client for domain-specific logic:
class CustomElasticClient extends \Babenkoivan\ElasticClient\ElasticClient
{
public function customMethod()
{
return $this->search('index', [...]);
}
}
Middleware: Add middleware to transform requests/responses:
ElasticClient::extend(function ($client) {
$client->before(function ($request) {
// Modify request
});
});
Event Listeners: Listen for Elasticsearch events (e.g., index creation):
ElasticClient::listen('index.created', function ($event) {
logger()->info("Index {$event->index} created.");
});
Index Aliases: Use aliases for zero-downtime reindexing:
ElasticClient::alias('posts', 'posts_v2');
Index Settings: Optimize for read-heavy workloads:
ElasticClient::indexSettings('posts', [
'number_of_replicas' => 0,
'refresh_interval' => '30s'
]);
Bulk API:
Prefer _bulk over individual _create/_update calls for batch operations.
Connection Pooling: Reuse connections for high-throughput applications:
$client = ElasticClient::connection('default');
// Reuse $client across requests
SSL/TLS:
Configure SSL in config/elastic.php:
'ssl' => [
'verification_mode' => 'none', // or 'full', 'host', 'peer'
'ca' => storage_path('certs/ca.pem'),
'cert' => storage_path('certs/client.crt'),
'key' => storage_path('certs/client.key'),
],
Sniffing: Enable host sniffing for dynamic clusters:
'sniff_on_start' => true,
'sniff_on_connection_fail' => true,
Environment Variables:
Use Laravel's .env for sensitive data:
ELASTIC_HOSTS=http://localhost:9200
ELASTIC_USERNAME=admin
ELASTIC_PASSWORD=secret
Reference in config:
'hosts' => explode(',', env('ELASTIC_HOSTS')),
How can I help you explore Laravel packages today?