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

Fos Elastica Bundle Laravel Package

runroom/fos-elastica-bundle

A maintained fork of FOSElasticaBundle that integrates Elasticsearch into Symfony apps via the Elastica PHP client. Define indexes and mappings, auto-index Doctrine entities through listeners, and query results with a repository-style finder supporting pagination and aggregations.

View on GitHub
Deep Wiki
Context7

Getting Started

Before you install anything, note the reality of this package: runroom/fos-elastica-bundle is an archived fork of the long-standing friendsofsymfony/elastica-bundle. The metadata (0 stars, 0 dependents, archived) means it is not a de-facto standard you should reach for on a greenfield project. Treat it as a compatibility/patched fork of upstream FOSElasticaBundle — evaluate upstream first, and only use this fork if you specifically need Runroom's patches (typically Symfony/Elastica version bumps). If you adopt it, pin the exact version and plan an exit path.

Assuming you are already on it (or comparing it to upstream), the setup path is:

  1. Install with Composer, matching the Elasticsearch server version to the Elastica client version the bundle supports:

    composer require runroom/fos-elastica-bundle
    

    Check composer.json constraints for Symfony, PHP, and ruflin/elastica — the bundle is only a thin integration layer; the ES version support comes from Elastica.

  2. Register the bundle in config/bundles.php (or bundles.php on older Symfony):

    FOS\ElasticaBundle\FOSElasticaBundle::class => ['all' => true],
    
  3. Configure clients and indexes in config/packages/fos_elastica.yaml:

    fos_elastica:
        clients:
            default:
                host: '%env(ELASTICSEARCH_HOST)%'
                port: 9200
        indexes:
            app:
                finder: ~
                persistence:
                    driver: orm
                    model: App\Entity\Product
                    provider: ~
                    listener: ~
                properties:
                    name: { type: text }
                    price: { type: float }
    
  4. First use case — index a Doctrine entity and search it. Run the populate command, then query through the finder service:

    bin/console fos:elastica:populate --index=app
    
    $finder = $this->container->get('fos_elastica.finder.app');
    $results = $finder->find('widget');
    

Where to look first: the bundle's DependencyInjection/Configuration.php is the authoritative schema for every option (it is more current than most docs), and bin/console debug:container fos_elastica lists the generated services and aliases.

Implementation Patterns

Mapper configuration lives in YAML (or PHP/XML), not annotations. The index definition is the source of truth for mappings, analyzers, and per-type persistence. Keep it in version control and treat mapping changes as schema migrations — see gotchas.

Finder usage. The bundle exposes one finder service per index (fos_elastica.finder.<index>). The common patterns:

$finder = $this->container->get('fos_elastica.finder.app');

// Raw results (arrays by default)
$results = $finder->find($query);

// Hydrated entities via the configured transformer
$results = $finder->findHybrid($query);

// Pagination for controllers
$paginator = $finder->findPaginated($query);

// Adapter for Pagerfanta/KnpPaginator
$adapter = $finder->createPaginatorAdapter($query);

Query objects are plain Elastica (Elastica\Query, Elastica\Query\BoolQuery, aggregations, etc.). The bundle does not abstract query building away, which is good — you get full ES expressiveness — but it means your query code is coupled to Elastica's API and version.

Persistence listeners vs. manual indexing. With persistence.listener: ~, Doctrine ORM postPersist/postUpdate/postRemove events index documents automatically. That is convenient but fragile at scale (see gotchas). For more control, drop the listener and index explicitly:

$index = $this->container->get('fos_elastica.index.app');
$index->addDocument(new \Elastica\Document($product->getId(), $serialized));

Custom providers. When the default ORM provider does not fit (e.g., you need aggregates, translations, or cross-entity data), implement the bundle's provider interface and register it as fos_elastica.provider.<index>.<type>. This is the standard extension point for anything that isn't a straight entity serialization.

Populate command flags are the day-to-day workhorse:

bin/console fos:elastica:populate --index=app --batch-size=500 --sleep=100
bin/console fos:elastica:populate --no-delete   # append instead of clean
bin/console fos:elastica:reset --index=app      # drop/recreate then populate

Use --sleep when indexing parent/child relationships or when the server needs backpressure. Use --batch-size to keep memory bounded.

Aliases for zero-downtime reindexing. Configure use_alias: true on the index; fos:elastica:reset then creates a new physical index and atomically repoints the alias. This is the recommended workflow for mapping changes instead of indexing in place.

Serializer integration. For JMS Serializer users, the bundle ships a serializer handler and callback provider. Configure serializer_groups per type and let the provider serialize entities rather than hand-building arrays. Keep groups narrow — over-serializing entities into ES is a common source of bloat and stale embedded data.

Testing. Give tests their own index configuration and clear it between runs. The bundle supports distinct index names per environment; if you can't prefix, at minimum fos:elastica:reset in a test bootstrap. Parallel test runners will collide on the same index name unless you isolate them.

Gotchas and Tips

  • It is archived. There will be no security or compatibility fixes from Runroom. Upstream FOSElasticaBundle is the maintained option. If you need this fork, pin a release, mirror it in your own VCS (Composer repositories + vcs type), and track upstream for fixes worth cherry-picking.

  • Version matrix is everything. Elastica's version determines which Elasticsearch servers work; the bundle's version determines which Symfony/PHP versions work. A mismatch produces runtime NoNodesAvailableException or 400s on mapping creation, not a helpful composer error. Check both constraints before upgrading either side.

  • Documents are not searchable until refresh. Default refresh_interval is 1s. During bulk populate, set refresh_interval: -1 and number_of_replicas: 0 on the target index, then restore after. Otherwise populate time balloons.

  • Doctrine listener pitfalls. The ORM listener indexes on flush but does not know about DQL updates, raw SQL, or bulk operations. It also fires inside the flush, which can cause recursion (repositories inside listeners triggering another flush) and can index entities in an inconsistent state if the flush fails downstream. For high-volume writes, disable the listener and index in a post-commit hook or via a queue consumer.

  • Mapping changes require a full reindex. There is no auto-migration. Bump the alias/index, reindex, flip the alias. Keep old indices around briefly for rollback.

  • nested mapping is not optional for nested queries. Querying a nested field without the mapping (or without wrapping the query in Elastica\Query\Nested) silently returns zero hits — a classic debugging trap.

  • Type shape changed in ES 7. The bundle's types/type configuration is a legacy of ES 6. On ES 7+ you use a single _doc type, and the mapping structure differs. Confirm the fork's mapping builder matches your server version; the YAML keys are not identical across ES majors.

  • Finder results are untyped by default. Without a transformer configured, find() returns arrays (the raw _source). If you expect entities, set finder: ~ and use findHybrid(), or configure a custom transformer. Mixing the two in one codebase causes subtle array vs. entity bugs.

  • Debugging. Inspect the cluster directly (curl localhost:9200/_cat/indices, _mapping, _search?explain=true) rather than guessing from PHP. In Symfony, debug:container fos_elastica shows the generated service ids — aliases can change between bundle versions, so resolve them rather than hardcoding.

  • Extension points, in rough order of usefulness: custom providers, the fos_elastica.client service for raw client access, decorating the finder, and a custom IndexBuilder/populator for non-standard data sources. Avoid subclassing the bundle's internals — they are not covered by a stability guarantee, especially in a fork.

  • Elasticsearch is not a database. Do not treat the index as authoritative. Keep the relational store as the source of truth and treat the index as a rebuildable cache; that mindset makes reindexing, failures, and version upgrades tractable.

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.
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle
adachsoft/api-version-bundle
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
cgv/localized-resource