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

Elastica Bundle Laravel Package

zenstruck/elastica-bundle

Zenstruck ElasticaBundle integrates the Elastica Elasticsearch client with Symfony, providing bundle configuration and service wiring for connecting Symfony applications to Elasticsearch with less boilerplate.

View on GitHub
Deep Wiki
Context7

Getting Started

This is a thin Symfony DI wrapper around the ruflin/elastica client — it does not provide entity mapping, automatic index population, or a repository layer. Start by understanding that scope: the bundle's only job is registering a configured Elastica\Client as a service.

Install and register

composer require zenstruck/elastica-bundle
// app/AppKernel.php (Symfony 2.x era)
public function registerBundles()
{
    $bundles = [
        // ...
        new Zenstruck\ElasticaBundle\ZenstruckElasticaBundle(),
    ];
}

Configure the client in app/config/config.yml:

zenstruck_elastica:
    clients:
        default:
            host: "%elasticsearch_host%"
            port: "%elasticsearch_port%"

Where to look first: the bundle's DependencyInjection/ folder — the Extension and Configuration classes define every config key and the service aliases (typically zenstruck_elastica.client.default, and a zenstruck_elastica.client alias pointing at the first client). Read these before guessing at config shapes.

First use case — inject the client and index a document:

use Elastica\Client;
use Elastica\Document;

class ProductIndexer
{
    public function __construct(private Client $client) {}

    public function index(array $row): void
    {
        $index = $this->client->getIndex('products');
        $index->getType('product')->addDocument(
            new Document($row['id'], $row)
        );
    }
}

Wire Elastica\Client to the bundle's service in your container (or use the explicit service id if autowiring isn't available).

Implementation Patterns

Inject the client, not a wrapper. Since there is no repository abstraction, the idiomatic pattern is to inject Elastica\Client (or the explicit zenstruck_elastica.client.<name> service) into your own small indexer/searcher services:

services:
    app.product_indexer:
        class: AppBundle\Search\ProductIndexer
        arguments: ['@zenstruck_elastica.client.default']

Multiple clients / clusters. Define more than one under clients: and address them by service id — useful for a writable cluster plus a read replica, or for separating analytics from search:

zenstruck_elastica:
    clients:
        default:  { host: es-write.internal, port: 9200 }
        read:     { host: es-read.internal,  port: 9200 }

Index and mapping bootstrap. The bundle does not create indexes for you. Add an idempotent console command or migration step that checks/creates the index and sets mappings:

if (!$client->getIndex('products')->exists()) {
    $client->getIndex('products')->create();
}
$type = $client->getIndex('products')->getType('product');
$type->setMapping([
    'name'  => ['type' => 'string'],
    'price' => ['type' => 'float'],
]);

Bulk for backfills. For populating an existing dataset, use Elastica's bulk API rather than per-document indexing — the difference is an order of magnitude at scale:

$bulk = new \Elastica\Bulk($client);
foreach ($rows as $row) {
    $bulk->addData(new Document($row['id'], $row), 'index', ['index' => 'products', 'type' => 'product']);
}
$bulk->send();

Searching stays entirely in Elastica's query DSL — build a Query, wrap in Query\Match/Query\BoolQuery, and call $index->search($query):

$query = new \Elastica\Query(new \Elastica\Query\Match('name', $term));
$results = $client->getIndex('products')->search($query);

Sync-on-write. Since there's no event subscriber, tie indexing to your domain events (Doctrine postPersist/postUpdate or a Symfony event listener) and keep the indexer as a discrete, testable service.

Testing. Point the client at a disposable ES instance in config_test.yml, drop index prefixes per test run, or swap Elastica\Client for a mock in unit tests — the thinness of the bundle makes this easy.

Gotchas and Tips

Version compatibility is the big one. This bundle last shipped in 2015 and pins to Elastica versions from that era (1.x/2.x), targeting Elasticsearch 1.x/2.x. Modern Elasticsearch (7.x/8.x) requires a much newer ruflin/elastica — you will not be able to use this bundle against a current cluster without significant patching. Verify the constraint in composer.json before adopting.

It is not FOSElasticaBundle. There is no automatic Doctrine integration, no index population, no listeners, no serializer. If you need those, this is the wrong tool — the whole package is a config-to-service bridge.

Very low adoption signal. With ~1 star, zero dependents, and no release since 2015, treat this as an abandoned personal package. For a new project, register the Elastica\Client yourself in three lines of YAML — you'd get identical behavior with no dead dependency.

Service id guessing. If autowiring isn't in play, log the container services (debug:container) to confirm the exact client ids the extension registers — naming conventions in older Zenstruck bundles occasionally differ from the obvious zenstruck_elastica.client.<name>.

Multiple-client default resolution. When you define several clients, check whether a zenstruck_elastica.client alias exists and which one it points at; injecting @zenstruck_elastica.client in a multi-client setup can silently give you the wrong cluster.

No config validation depth. Older extensions often accept sparse config and pass it straight to Elastica\Client. A missing host/port will fail at connection time, not at container compile time — set sensible defaults in parameters and reference them.

Extension points are minimal. There is no Elastica\Client factory hook or compiler pass for customization beyond config; if you need connection options the bundle doesn't expose, define your own Elastica\Client service and skip the bundle entirely.

Debugging search results. Elastica\Response exposes getData() and getQuery() — dump the raw response when queries return nothing unexpected; silent mapping mismatches (e.g., string vs text/keyword) are the most common cause and are indistinguishable until you inspect the raw JSON.

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.
skyraptor/chatter
edlugz/sasapay
abbasudo/artisan-route
mirvan/ippanel
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource