Installation:
composer require baks-dev/elastic
php bin/console baks:assets:install
config/packages/baks_elastic.yaml).Basic Configuration:
Edit config/packages/baks_elastic.yaml:
baks_elastic:
clients:
default:
host: 'http://localhost:9200'
index_prefix: 'laravel_'
First Use Case: Inject the client into a service/controller:
use BaksDev\Elastic\Client\ElasticClient;
public function __construct(private ElasticClient $elasticClient) {}
public function indexData()
{
$indexName = 'products_v1';
$this->elasticClient->index('product', $indexName, ['name' => 'Laptop', 'price' => 999.99]);
}
Key Classes to Explore:
ElasticClient (main facade)ElasticQueryBuilder (for complex queries)ElasticIndexManager (for index operations)// Index a document
$this->elasticClient->index('product', 'products_v1', $data);
// Get a document
$result = $this->elasticClient->get('product', 'products_v1', 'doc_id');
// Update a document
$this->elasticClient->update('product', 'products_v1', 'doc_id', ['price' => 899.99]);
// Delete a document
$this->elasticClient->delete('product', 'products_v1', 'doc_id');
// Basic search
$results = $this->elasticClient->search('products_v1', [
'query' => ['match' => ['name' => 'Laptop']],
'size' => 10
]);
// Aggregations
$results = $this->elasticClient->search('products_v1', [
'aggs' => [
'price_stats' => ['stats' => ['field' => 'price']]
]
]);
// Create an index
$this->elasticClient->createIndex('products_v1', [
'mappings' => [
'properties' => [
'name' => ['type' => 'text'],
'price' => ['type' => 'float']
]
]
]);
// Check index exists
if ($this->elasticClient->indexExists('products_v1')) {
// ...
}
$bulkData = [
['index' => ['_index' => 'products_v1', '_id' => '1']],
['name' => 'Mouse', 'price' => 19.99],
['index' => ['_index' => 'products_v1', '_id' => '2']],
['name' => 'Keyboard', 'price' => 49.99]
];
$this->elasticClient->bulk($bulkData);
// In a Product model
public function syncToElastic()
{
$this->elasticClient->index(
'product',
'products_v1',
$this->toArray()
);
}
// In a service
public function searchProducts(string $query)
{
return $this->elasticClient->search('products_v1', [
'query' => ['multi_match' => ['query' => $query, 'fields' => ['name^3', 'description']]]
]);
}
Extend ElasticQueryBuilder for reusable queries:
use BaksDev\Elastic\Query\ElasticQueryBuilder;
class ProductQueryBuilder extends ElasticQueryBuilder
{
public function byPriceRange(float $min, float $max): self
{
$this->query['range'] = ['price' => ['gte' => $min, 'lte' => $max]];
return $this;
}
}
Use Laravel events to sync models to Elasticsearch:
// In a service provider
Event::listen(ProductSaved::class, function (ProductSaved $event) {
$event->product->syncToElastic();
});
$scroll = $this->elasticClient->scroll('products_v1', [
'size' => 100,
'scroll' => '2m'
]);
while (!empty($scroll['hits']['hits'])) {
// Process batch
$scroll = $this->elasticClient->scroll('products_v1', [
'scroll' => '2m',
'scroll_id' => $scroll['_scroll_id']
]);
}
Dispatch bulk operations to queues:
SyncToElastic::dispatch($model)->onQueue('elastic');
Index Naming Conflicts:
index_prefix in config to avoid clashes with other services.index_prefix: 'app_' → indices like app_products_v1.Mapping Errors:
mapper_parsing_exception if data doesn’t match mappings.dynamic: 'strict' in mappings or update mappings before indexing.Connection Timeouts:
baks_elastic:
clients:
default:
timeout: 60
Bulk Operation Failures:
$this->elasticClient->setLogger($this->app->make(MonologLogger::class));
PHP 8.4+ Strict Types:
string for index names).Enable Debug Mode:
baks_elastic:
debug: true
storage/logs/elastic.log.Check Index Settings:
$settings = $this->elasticClient->getIndexSettings('products_v1');
Validate Queries:
Use the _validate/query API:
$this->elasticClient->validateQuery('products_v1', [
'query' => ['match' => ['name' => 'Laptop']]
]);
Handle Retries: Configure retry logic for transient failures:
$this->elasticClient->setRetryConfig([
'max_attempts' => 3,
'delay' => 100 // ms
]);
Custom Clients: Register additional clients in config:
baks_elastic:
clients:
analytics:
host: 'http://analytics-elastic:9200'
index_prefix: 'analytics_'
Middleware: Add request/response middleware:
$client->addMiddleware(function ($request, callable $next) {
$request->setHeader('Authorization', 'Bearer ' . config('elastic.token'));
return $next($request);
});
Event Listeners:
Extend core events (e.g., ElasticIndexCreated):
Event::listen(ElasticIndexCreated::class, function ($event) {
// Notify Slack/email
});
Testing:
Use the ElasticTestCase trait for unit tests:
use BaksDev\Elastic\Testing\ElasticTestCase;
class ProductTest extends ElasticTestCase
{
protected function setUp(): void
{
$this->createTestIndex('products_v1');
}
}
Environment-Specific Hosts: Override hosts per environment:
# config/packages/baks_elastic.yaml
baks_elastic:
clients:
default:
host: '%env(ELASTIC_HOST)%'
SSL/TLS: Enable for secure connections:
baks_elastic:
clients:
default:
ssl: true
ssl_verification: true
ssl_cert: '/path/to/cert.pem'
Authentication: Use API keys or basic auth:
baks_elastic:
clients:
How can I help you explore Laravel packages today?