spatie/elasticsearch-query-builder
Lightweight fluent PHP query builder for Elasticsearch. Build searches, filters, and aggregations with a clean API, then execute via the official client. Designed to pair with Spatie’s search-string parser; covers common use cases and is easy to extend.
Builder class abstracts low-level Elasticsearch DSL, making it ideal for Laravel applications where maintainability and readability are priorities.BoolQuery, NestedQuery) and aggregations, enabling granular control over complex search logic without coupling to a single use case.Elastic\Elasticsearch\Client) and can be extended with Laravel-specific features (e.g., caching responses, logging queries).elasticsearch/elasticsearch PHP client (v8+), which is already a dependency for most Laravel Elasticsearch integrations (e.g., scout-elasticsearch). No additional infrastructure changes are needed.Builder instance into controllers/services.Cache::remember) to cache raw Elasticsearch payloads or responses, reducing API calls for repeated queries.script_score, parent/child queries, or runtime fields). Assess whether these are critical for your use case or if workarounds (e.g., raw payload injection via Builder::getPayload()) suffice.knn for vector search, eql for exact value queries)? If so, evaluate the effort to extend the package or use raw payloads.Builder instance to the container for dependency injection:
$this->app->singleton(Builder::class, function ($app) {
return new Builder($app->make(ElasticsearchClient::class));
});
ElasticsearchQuery) to simplify usage in Blade/views or controllers:
use Illuminate\Support\Facades\ElasticsearchQuery;
$results = ElasticsearchQuery::builder()
->index('products')
->addQuery(MatchQuery::create('name', request('q')))
->search();
Builder to support Scout’s search method signature, enabling seamless migration of existing Scout queries:
class ScoutElasticsearchBuilder extends Builder
{
public function search($query): array
{
return $this->addQuery($query)->search();
}
}
Builder to validate the API’s fit and performance impact.Builder for all new Elasticsearch queries via a custom macro or trait:
trait UsesElasticsearchBuilder
{
protected function elasticsearchQuery(): Builder
{
return app(Builder::class)->index($this->index);
}
}
Builder, using deprecation warnings or static analysis tools (e.g., PHPStan) to enforce adoption.scout-elasticsearch, elasticsearch-laravel), verify no conflicts exist (e.g., duplicate client instances).composer require spatie/elasticsearch-query-builder elasticsearch/elasticsearch
config/services.php:
'elasticsearch' => [
'hosts' => [
['host' => 'localhost', 'port' => 9200],
],
],
MatchQuery, RangeQuery) in controllers or services.TermsAggregation, AvgAggregation) for analytics or faceted search.$client = Mockery::mock(Client::class);
$client->shouldReceive('search')->andReturn($mockResponse);
composer.json if stability is critical:
"spatie/elasticsearch-query-builder": "2.0.0"
Builder::getPayload() method to inspect raw Elasticsearch queries for debugging. Log payloads in development:
\Log::debug('Elasticsearch query payload', ['payload' => $builder->getPayload()]);
_validate/query API to validate payloads before execution.Builder::search() calls in try-catch blocks to handle Elasticsearch exceptions (e.g., Elastic\Exception\ElasticsearchException):
try {
$results = $builder->search();
} catch (\Exception $e) {
\Log::error('Elasticsearch query failed', ['error' => $e->getMessage()]);
abort(500, 'Search service unavailable');
}
_source fields to reduce payload size.filter context for queries that don’t need scoring (e.g., faceted navigation).search_after for deep result sets.$results = Cache::remember("elasticsearch:{$index}:{$queryHash}", now()->addHours(1), function () use ($builder) {
return $builder->search();
});
How can I help you explore Laravel packages today?