Weave 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

A lightweight, fluent PHP API for building and executing ElasticSearch queries. Chain queries and aggregations, then call search(). Built for Spatie's search-string-parser but flexible enough to cover most common use cases.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit

  • The package is a thin, framework-agnostic query-construction layer over the official elasticsearch/elasticsearch PHP client (Elastic\Elasticsearch\Client). It is not a Laravel package: no service provider, no config file, no facade, no Eloquent/Scout integration. Treat it as a library, not a Laravel module.
  • It belongs in the query authoring slot of a search stack, not the transport or index management slot. Connection building, auth, retries, and cluster config remain the responsibility of the Elasticsearch client and your own configuration layer.
  • It is explicitly scoped as the companion to spatie/elasticsearch-search-string-parser. That means the query-type coverage is driven by Spatie's own use cases (match, multi-match, term(s), bool, nested, range, geo-shape, regexp, wildcard, percolate, collapse, inner hits, plus a broad aggregation set). Anything outside that surface requires either a PR or the raw payload escape hatch.
  • The getPayload() method is the architectural release valve: teams can build 80–90% of a query fluently and inject hand-written DSL fragments for the remainder without abandoning the abstraction. This materially lowers the "abstraction traps you" risk.

Integration feasibility

  • Very low integration cost. composer require spatie/elasticsearch-query-builder, instantiate Builder with a client, call search(). No migrations, no schema, no DI wiring beyond binding the client in the container.
  • Critical version coupling: package v2+ targets the ES PHP client v8 (README states v1 is required for elasticsearch/elasticsearch v7). Verify the matrix against your actual ES server version and PHP client major before adopting.
  • Complements rather than competes with Laravel Scout. If the product needs Scout-style model indexing, this package does not provide it; if the product needs precise DSL control (boosting, fuzziness, nested inner hits, collapse, aggregations), Scout does not provide it and this package does.

Technical risk

  • Coverage risk (medium): documented as "covers most use-cases but might lack certain features." Any feature gap surfaces as either a code contribution or a fallback to raw DSL — both acceptable, but the fallback should be a designed path, not an incident-time improvisation.
  • Version-drift risk (medium): Elasticsearch's query DSL evolves across majors, and this package's release cadence is tied to maintainer availability, not Elastic's. A cluster upgrade can strand the package a major behind.
  • Ecosystem-signal risk (medium): 181 stars and zero dependents is a weak proxy for production hardening. Low dependents means few public case studies of edge-case behavior; you are effectively an early-ish adopter.
  • Bus-factor / support risk (medium): MIT, Spatie-maintained, CHANGELOG and tagged releases present, but no commercial SLA (Spatie's paid support covers their commercial products, not necessarily this package). Issue triage and PR merge timeliness are unknown.
  • Low technical-complexity risk: the package is small and mostly deterministic array construction. Worst case, forking or vendoring is cheap. This is the mitigant that makes the other risks tolerable.
  • No hidden runtime risk: it does not manage connections, caching, or background work. Failure surface is essentially "did we generate a valid DSL payload."

Key questions

  1. Which Elasticsearch server version(s) will production run, and is the PHP client major aligned with the package major (v2 for client v8, v1 for client v7)? Is an ES 9 path on the maintainer's roadmap?
  2. Which query features does the product roadmap actually require (semantic/kNN, vector search, RRF, search_after, point-in-time, collapse + inner hits)? Which of these are absent, and are we prepared to submit PRs versus fall back to getPayload()?
  3. Where does the client get constructed and configured (service provider, config file, secrets manager)? Who owns cluster topology, auth, and TLS configuration?
  4. Do we already have a raw-DSL or Scout-based implementation? If so, is the migration justified by measurable query-authoring pain, or is this a net-new capability?
  5. Do we accept a fork-and-maintain contingency, or does that constitute an unacceptable operational liability for this team?

Integration Approach

Stack fit

  • Fits any Laravel 9/10/11+ application on PHP 8.1+ that already talks to Elasticsearch through the official client. It slots cleanly behind an application-owned interface (e.g., SearchRepository / SearchService) so that Builder, Query objects, and raw responses do not leak into controllers or domain models.
  • Recommended layering: Controller/Job → Domain search service → query builder (this package) → Elastic\Elasticsearch\Client → cluster. The domain service is the seam that lets you swap or fork the package later.
  • If Scout is in use for model indexing, keep Scout for indexing and use this package only for bespoke search endpoints — do not try to force it into a Scout driver.

Migration path

  • For teams currently hand-writing DSL arrays: adopt incrementally per endpoint. Build the query both ways in a test harness, assert the payloads are equivalent, then cut over. getPayload() makes this diffable without executing searches.
  • For teams on Scout's default search: leave it alone. Introduce this package only where relevance tuning is actually required; a partial migration is the correct scope.
  • For greenfield: start with this package for all query construction, and establish a documented convention for the raw-DSL escape hatch (e.g., a RawQuery wrapper or a getPayload() post-processing hook) so that gaps never block delivery.

Compatibility

  • Confirm the three-way alignment: ES server version ↔ elasticsearch/elasticsearch major ↔ spatie/elasticsearch-query-builder major. Lock all three in composer.json and in the deployment image.
  • Aggregations that depend on newer ES features (e.g., FilterAggregation with nested sub-aggregations, percolate behavior changes, collapse semantics) should be validated against the target cluster version, not just against the package's test suite.
  • NestedQuery::create(...) accepts a Query instance rather than only a static factory — confirm constructor vs. create() usage in the version you pin, as the README shows both forms.

Sequencing

  1. Spike (days): pin versions, stand up a throwaway cluster or testcontainer, reproduce 5–10 representative product queries (fuzzy match, bool with must_not, nested with inner hits, terms aggregation, collapse). Measure how much raw DSL is still required.
  2. Abstraction: define the search service interface and the raw-DSL escape hatch before writing feature queries.
  3. Test infrastructure: contract tests that execute against a real cluster in CI (payload snapshots alone will not catch DSL incompatibilities with the server).
  4. Pilot: one production search endpoint, instrumented for latency and error rates.
  5. Rollout: remaining endpoints in priority order, with the raw-DSL fallback documented from day one.

Operational Impact

Maintenance

  • Low code-volume, low-complexity dependency: roughly a "review on each minor release, patch promptly on client-major bumps" cadence. Budget a small recurring slice of engineering time, not a standing allocation.
  • The real maintenance burden is not the package — it is Elasticsearch itself (index mapping changes, reindex jobs, cluster upgrades). The package adds negligible overhead to that workload.
  • Fork readiness should be assessed once at adoption: if the package is vendored/forked, maintenance becomes a first-class owned cost; if not, the risk is deferred to upgrade time.

Support

  • MIT with no commercial SLA. Community issues and PRs only. Escalation path is effectively "we fix it ourselves," which is viable given the codebase size but must be an accepted policy, not an assumption.
  • Internal support model: designate one engineer as the search-stack owner who can review package releases, validate DSL changes, and shepherd upstream PRs.

Scaling

  • The package does not affect horizontal scaling; it produces a payload. Throughput and latency characteristics are entirely those of the cluster, the client's connection pooling, and query shape.
  • Query-authoring code scales fine — builders are cheap objects constructed per request. Watch for accidental builder reuse across requests if builders are cached or bound as singletons, since addQuery() mutates state.
  • Pagination helpers cover standard from/size; deep pagination (search_after, point-in-time) is likely out of scope and should be evaluated against the roadmap question above.

Failure modes

  • Invalid DSL emitted → 400 from the cluster at runtime. This is the primary failure mode and it is a late failure (no compile-time validation). Mitigation: contract tests against a real cluster, plus payload logging on error.
  • Version incompatibility → silently ignored or rejected query clauses after a cluster or client upgrade. Mitigation: pin versions; run the contract test suite before any upgrade.
  • Feature gap → developer writes raw arrays ad hoc, fragmenting query style across the codebase. Mitigation: enforce the escape hatch through a single documented wrapper.
  • Mutable builder state bleed if builders are shared across requests. Mitigation: construct per request; treat builders as request-scoped, never as singletons.
  • Maintainer abandonment (low likelihood, low impact given size). Mitigation: fork contingency documented; no hard dependency on upstream velocity for delivery.
  • Misdiagnosed relevance problems: because the abstraction hides the final DSL, debugging poor search results requires dumping getPayload(). Teams must build that into their debugging runbook from day one.

Ramp-up

  • Very shallow learning curve for anyone who already understands Elasticsearch query DSL, because the API is a near-1:1 mirror of the DSL with static create() factories and named arguments. A PHP developer familiar with ES can be productive in hours.
  • The inverse is true for developers who do not know the DSL: the fluent API makes it easy to produce plausible-looking queries with wrong semantics (e.g., match vs term on an analyzed field, must vs filter affecting scoring and caching). Onboarding must include a short DSL literacy component, not just package API documentation.
  • Documentation quality is good (README is comprehensive, per-query links to Elastic docs, explicit version note for client v7). Training material can largely be the README plus internal conventions.
  • Overall verdict from a TPM lens: low-cost, low-lock-in, moderate-signal dependency. Adopt where bespoke relevance tuning is a real product requirement, gate it behind an internal search-service seam, and treat the raw-DSL escape hatch and cluster-version contract tests as non-negotiable prerequisites rather than nice-to-haves.
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.
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums
rlacerda83/query-parser
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings