Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Elasticsearch Query Builder Laravel Package

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.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture Fit

  • Fluent Query Builder Pattern: Aligns well with Laravel’s expressive syntax (e.g., Eloquent, Scout) and reduces boilerplate for Elasticsearch queries. The Builder class abstracts low-level Elasticsearch DSL, making it ideal for Laravel applications where maintainability and readability are priorities.
  • Modularity: Supports composable queries (e.g., BoolQuery, NestedQuery) and aggregations, enabling granular control over complex search logic without coupling to a single use case.
  • Laravel Ecosystem Synergy: Integrates seamlessly with Laravel’s service container (via Elastic\Elasticsearch\Client) and can be extended with Laravel-specific features (e.g., caching responses, logging queries).

Integration Feasibility

  • Elasticsearch Client Compatibility: Requires the official 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.
  • Laravel Service Provider: Can be bootstrapped via a Laravel service provider to centralize client configuration (e.g., cluster settings, retry logic) and inject the Builder instance into controllers/services.
  • Query Caching: Can be layered with Laravel’s cache (e.g., Cache::remember) to cache raw Elasticsearch payloads or responses, reducing API calls for repeated queries.

Technical Risk

  • Version Locking: The package explicitly notes compatibility with Elasticsearch PHP client v8+ (v7 requires v1 of the package). Ensure your project’s Elasticsearch client version aligns with this requirement.
  • Limited Advanced Features: Missing support for some Elasticsearch features (e.g., 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.
  • Performance Overhead: Fluent builders may introduce minor overhead for simple queries. Benchmark against raw Elasticsearch queries if performance is critical (e.g., high-throughput APIs).

Key Questions

  1. Use Case Scope:
    • Are you primarily building search-as-you-type (e.g., autocomplete), faceted search, or analytics-driven aggregations? The package excels at the former but may require extensions for the latter.
  2. Query Complexity:
    • Do you need support for Elasticsearch features not covered by the package (e.g., knn for vector search, eql for exact value queries)? If so, evaluate the effort to extend the package or use raw payloads.
  3. Team Familiarity:
    • Is your team comfortable with Elasticsearch’s query DSL, or does the fluent API reduce the learning curve? The package abstracts complexity but may obscure debugging for advanced queries.
  4. Testing Strategy:
    • How will you test queries? The package supports mocking the Elasticsearch client, but integration tests with a real cluster may be necessary for edge cases (e.g., pagination, aggregations).
  5. Long-Term Maintenance:
    • Will you contribute missing features (e.g., new query types) or rely on community updates? The MIT license allows forks, but Spatie’s roadmap may not align with your needs.

Integration Approach

Stack Fit

  • Laravel Integration:
    • Service Container: Bind the Elasticsearch client and Builder instance to the container for dependency injection:
      $this->app->singleton(Builder::class, function ($app) {
          return new Builder($app->make(ElasticsearchClient::class));
      });
      
    • Facade: Create a facade (e.g., 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();
      
  • Scout Integration:
    • If using Laravel Scout with Elasticsearch, extend the 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();
          }
      }
      

Migration Path

  1. Phase 1: Pilot Queries
    • Replace 2–3 critical Elasticsearch queries (e.g., search, filters) with the Builder to validate the API’s fit and performance impact.
    • Example: Migrate a product search endpoint from raw DSL to the fluent builder.
  2. Phase 2: Standardize Usage
    • Enforce the 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);
          }
      }
      
  3. Phase 3: Deprecate Raw DSL
    • Gradually phase out direct Elasticsearch client usage in favor of the Builder, using deprecation warnings or static analysis tools (e.g., PHPStan) to enforce adoption.

Compatibility

  • Elasticsearch Client: Ensure compatibility with your Elasticsearch cluster version (e.g., v7.x vs. v8.x). Test with the exact client version used in production.
  • Laravel Version: No Laravel-specific dependencies, but test with your Laravel version (e.g., 10.x) to catch potential namespace or method conflicts.
  • Third-Party Packages: If using other Elasticsearch packages (e.g., scout-elasticsearch, elasticsearch-laravel), verify no conflicts exist (e.g., duplicate client instances).

Sequencing

  1. Setup:
    • Install the package and Elasticsearch client:
      composer require spatie/elasticsearch-query-builder elasticsearch/elasticsearch
      
    • Configure the Elasticsearch client in config/services.php:
      'elasticsearch' => [
          'hosts' => [
              ['host' => 'localhost', 'port' => 9200],
          ],
      ],
      
  2. Basic Queries:
    • Implement simple queries (e.g., MatchQuery, RangeQuery) in controllers or services.
  3. Aggregations and Sorting:
    • Add aggregations (e.g., TermsAggregation, AvgAggregation) for analytics or faceted search.
  4. Advanced Features:
    • Extend the package for unsupported features (e.g., custom aggregations) or use raw payloads for edge cases.
  5. Testing:
    • Write unit tests for query builders and integration tests for critical endpoints.
    • Mock the Elasticsearch client in unit tests:
      $client = Mockery::mock(Client::class);
      $client->shouldReceive('search')->andReturn($mockResponse);
      

Operational Impact

Maintenance

  • Package Updates:
    • Monitor Spatie’s release cycle for breaking changes (e.g., Elasticsearch client version bumps). Test updates in a staging environment.
    • Consider pinning the package version in composer.json if stability is critical:
      "spatie/elasticsearch-query-builder": "2.0.0"
      
  • Custom Extensions:
    • Document any custom query types or aggregations added to the package to avoid knowledge silos.
    • Contribute back to the package if extensions are generally useful (e.g., via PRs).

Support

  • Debugging:
    • Leverage the Builder::getPayload() method to inspect raw Elasticsearch queries for debugging. Log payloads in development:
      \Log::debug('Elasticsearch query payload', ['payload' => $builder->getPayload()]);
      
    • Use Elasticsearch’s _validate/query API to validate payloads before execution.
  • Error Handling:
    • Wrap 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');
      }
      
  • Support Channels:
    • Use GitHub issues for package-related bugs or feature requests.
    • For Elasticsearch-specific issues, consult the Elasticsearch forums or official documentation.

Scaling

  • Query Optimization:
    • Profile slow queries using Elasticsearch’s profiling API or APM tools. Optimize by:
      • Limiting _source fields to reduce payload size.
      • Using filter context for queries that don’t need scoring (e.g., faceted navigation).
      • Implementing pagination with search_after for deep result sets.
  • Caching:
    • Cache frequent queries or aggregations at the application level (e.g., Redis):
      $results = Cache::remember("elasticsearch:{$index}:{$queryHash}", now()->addHours(1), function () use ($builder) {
          return $builder->search();
      });
      
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope
anil/file-picker
broqit/fields-ai