friendsofsymfony/elastica-bundle
FOSElasticaBundle integrates Elasticsearch and the Elastica library into Symfony, with configurable index mappings and Doctrine event listeners for automatic indexing. Version 7 supports Elasticsearch 8 and 9 on Symfony 6.4+ and PHP 8.1+.
Architecture fit — low for a Laravel target. This is a Symfony bundle, not a framework-agnostic PHP package. FOSElasticaBundle's value is delivered almost entirely through Symfony's dependency-injection container, its Extension/compiler-pass configuration loading (config/packages/fos_elastica.yaml), its Flex recipe, and Symfony's event dispatcher. Laravel has no bundle system, no DI extension lifecycle, and no equivalent config-key-to-service wiring. Dropping the package into a Laravel composer.json is mechanically possible but architecturally inert: you would get a Bundle class that nothing registers, plus a configuration schema that nothing reads.
What is genuinely reusable. Three things survive outside Symfony:
LengthAwarePaginator.ruflin/elastica and the official elasticsearch/elasticsearch PHP client are ordinary Composer packages usable from Laravel directly.Integration feasibility. The headline feature — Doctrine ORM/ODM event listeners for automatic indexing — is dead code in an Eloquent application. Replicating it means writing Eloquent observers, which is a reimplementation, not an integration. You would also pull in symfony/http-kernel, symfony/dependency-injection, symfony/config, symfony/serializer, symfony/messenger, doctrine/persistence, and pagerfanta alongside their Illuminate counterparts: two serializers, two event dispatchers, two queue abstractions, and a persistence layer the app does not use. That is dependency surface with no functional payoff.
Technical risk.
connections layer was removed, host/port/url collapsed into hosts, SSL moved under client_config, index_template.template renamed to index_patterns, and request/exception event payloads switched to PSR-7. The overwhelming majority of blog posts, Stack Overflow answers, and third-party tutorials predate this. Any team copying examples will produce silently wrong configuration.Key questions for the requester.
Stack fit. If the target is Laravel, do not install this bundle. Build the capability from the primitives:
elasticsearch/elasticsearch 8.x (or ruflin/elastica standalone) as the transport.FinderInterface / PaginatedFinderInterface.ResetterInterface / AliasProcessor.LengthAwarePaginator — the analog to FantaPaginatorAdapter.If the target is genuinely Symfony, the bundle is the correct and low-risk choice: composer require friendsofsymfony/elastica-bundle, apply the Flex recipe, define fos_elastica.yaml, then populate via the bundle's console command.
Migration path (Laravel-oriented).
config/search.php, keeping per-index settings and mappings explicit rather than relying on ES dynamic mapping.Compatibility. PHP 8.1+ is satisfied by current Laravel releases, so the blocker is not the language runtime — it is the transitive Symfony/Doctrine/pagerfanta dependency graph and the duplicated serializer and event-dispatcher stacks. Treat those as disqualifying for a pure Laravel app rather than as obstacles to work around.
Sequencing. Do the vertical slice first: one model, one index, observer-driven writes, one search endpoint with pagination. Prove relevance and latency before generalizing. Reindex tooling and alias-swap automation come second — they are the operational backbone and should not be deferred to "phase 2." Adding additional index types comes last, once the transformer and query builder contracts have stabilized.
Maintenance. The project is mature and maintained but explicitly tracks Symfony's release train, with periodic hard BC breaks (v6.0.0 and v7.0.0 were both substantial). Every internal runbook, config sample, and onboarding doc must be pinned to v7+ config shape, because the pre-v7 connections-based examples are now invalid and remain widely published. If you instead adopt the underlying client libraries directly, the maintenance burden transfers to your team — but it is burden you would have carried anyway to bridge the framework gap.
Support. MIT-licensed, community/volunteer maintained, no vendor SLA. Documentation and release notes are solid, but the reported dependent count of 0 means you cannot lean on a broad downstream ecosystem for rapid fixes. Budget for internal ownership: at least one engineer fluent in Elasticsearch mapping design, query DSL, and relevance tuning. That expertise — not bundle familiarity — is the actual critical path.
Scaling. The bundle itself is thin; scaling is an Elasticsearch cluster concern — shard/replica sizing, refresh interval, bulk batch size, and queue depth. The async persister path (Messenger for Symfony; Horizon/Redis for a Laravel port) is the primary pressure valve and should be the default for anything beyond trivial write volume. Synchronous, in-request indexing is the most common self-inflicted scaling failure; the bundle mitigates this with deferred/terminate-listener persistence, and any reimplementation must reproduce that behavior. Hybrid pagination (database-backed pagers feeding the index) is the highest-risk scaling pattern and should be avoided unless depth beyond the ES result window is a hard requirement.
Failure modes.
index_patterns) and removed options read as silently misapplied configuration rather than loud errors.Ramp-up.
How can I help you explore Laravel packages today?