steamulo/elastica-fast-populate-bundle
A Symfony bundle that speeds up populating Elastica results from Elasticsearch responses, reducing per-document overhead when hydrating large result sets. It streamlines object population so search-heavy applications return structured data faster with less boilerplate.
Install both bundles. This is a companion to FOSElasticaBundle, not a replacement. You need FOSElasticaBundle already indexing data before this package does anything useful.
composer require steamulo/elastica-fast-populate-bundle
Register the bundle in config/bundles.php (for Symfony 4+):
STM\ElasticaFastPopulateBundle\STMElasticaFastPopulateBundle::class => ['all' => true],
Configure a real message transport. Because the whole point is distributing work to consumers, the bundle is only useful when messages leave the process. In practice that means a queued transport (AMQP/RabbitMQ, Redis, Doctrine, or Beanstalkd via Symfony Messenger), not sync. Look at the bundle's DependencyInjection/Configuration.php and its service definitions first — this is a low-star package, so the source is the documentation.
First use case: run the populate command the bundle exposes (typically a variant of fos:elastica:populate) and then start a pool of workers:
php bin/console <populate-command> --index=product
php bin/console messenger:consume <transport_name> --time-limit=3600
With a handful of workers running concurrently, you should see wall-clock time drop compared to the single-threaded fos:elastica:populate, especially on indices with tens of thousands of documents or more.
Fan-out populate with N workers. The core pattern is: producer slices the index into batches, each batch becomes a message, workers index those batches in parallel. Run several messenger:consume processes (Supervisor / systemd units) sized to your Elasticsearch cluster's write capacity, not to your CPU count.
Per-index/per-type invocation. Populate one index at a time rather than all indices in one command, so a failure is scoped and retries are cheap:
php bin/console <populate-command> --index=product --type=product
Wire into a deploy/migration step. A typical workflow: after schema changes or a fresh ES cluster spin-up, run the populate command in CI/deploy tooling, let workers drain the queue, then flip traffic. Pair it with FOSElasticaBundle's alias/reindex strategy so reads never go to a half-populated index.
Idempotent batch handlers. Treat each batch message as "index documents with IDs X..Y, replacing existing docs." On retry, the same message can safely re-index. This makes the queue tolerant of worker crashes.
Progress visibility. Since work is spread across workers, you lose the single-process progress bar. Track progress by logging per-batch counts (in your message handler or via a middleware) and compare against the source count (COUNT(*) on the ORM side) or against _cat/indices doc counts on the ES side.
Retry & poison-message handling. Configure the transport with a retry strategy (e.g. max_retries: 3, exponential backoff) and a failure transport. Individual batches failing on a single malformed row is the most common failure mode; you want those isolated to one message, not the whole populate.
sync transport defeats the purpose. If the Messenger transport is sync, you've replaced one slow command with one equally slow command plus dispatch overhead. Verify the transport in config/packages/messenger.yaml before benchmarking.refresh_interval: -1 (or a large value) on the target index, then a refresh when done. This bundle doesn't magically do that for you; enable it manually or in your populate orchestration.--time-limit or --memory-limit, and use --no-debug to avoid the profiler holding references.Command/ and Message//MessageHandler/ directories directly. Pin the version in composer.json and be prepared to fork if you hit a Symfony 7 compatibility issue.routing_key, that the consumer is listening on the right transport, and whether the producer is throwing on serialization (a common issue when messages carry entity references instead of IDs).stm_elastica_fast_populate (or similarly named) config key; failing that, decorate FOSElasticaBundle's provider/indexer service or override the message handler to control slicing.How can I help you explore Laravel packages today?