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

Ongr Elasticsearch Bundle Laravel Package

stexaz/ongr-elasticsearch-bundle

A Symfony bundle for integrating Elasticsearch with ONGR, providing document mapping, index management, repositories, and search tooling for scalable full-text search and filtering in PHP apps. It streamlines configuration and query building while keeping Elasticsearch usage idiomatic in Symfony.

View on GitHub
Deep Wiki
Context7

Getting Started

This bundle is a fork of the (now abandoned) ONGR ElasticsearchBundle for Symfony. Last release was October 2017, zero dependents, so treat it as something you'd only adopt inside an existing legacy Symfony 2.8/3.x project pinned to Elasticsearch 2.x/5.x — not as a greenfield choice. Everything below assumes that context.

1. Install with pinned versions

composer require stexaz/ongr-elasticsearch-bundle "^5.0"

You will also need a matching elasticsearch/elasticsearch client (the ONGR line of that era targeted the ~5.x client) and a running Elasticsearch of the same major version. Do not let Composer float this package — lock the bundle and the client.

2. Register the bundle

Symfony 3 — app/AppKernel.php:

$bundles = [
    // ...
    new ONGR\ElasticsearchBundle\ONGRElasticsearchBundle(),
];

Symfony 4 — config/bundles.php:

return [
    // ...
    ONGR\ElasticsearchBundle\ONGRElasticsearchBundle::class => ['all' => true],
];

3. Configure it — config/config.yml (or config/packages/ongr_elasticsearch.yaml):

ongr_elasticsearch:
    indexes:
        default:
            index_name: app_%kernel.environment%
            hosts: ["%elasticsearch_host%:9200"]
            document_directories:
                - "%kernel.root_dir%/../src/AppBundle/Document"

4. Annotate your first document — this is where to look first. The annotation layer is the heart of the package:

namespace AppBundle\Document;

use ONGR\ElasticsearchBundle\Annotation as ES;

/**
 * @ES\Document(type="product")
 */
class Product
{
    /** @ES\Id() */
    public $id;

    /** @ES\Property(type="text", name="title") */
    public $title;

    /** @ES\Property(type="keyword", name="sku") */
    public $sku;
}

5. First use case — create the index and index one document

bin/console ongr:es:index:create --index=default
$manager = $this->get('ongr_elasticsearch.manager'); // Manager service

$product = new Product();
$product->id = 'p-1';
$product->title = 'Blue widget';
$product->sku = 'BW-1';

$manager->persist($product);
$manager->commit();   // flushes the bulk buffer for this index
$manager->getRepository(Product::class)->find('p-1');

If bin/console ongr:es:index:create runs cleanly and find() returns your object, the bundle is wired correctly. If the console command is missing, the bundle is not registered (or the DI extension failed silently on a Symfony version mismatch).

Implementation Patterns

Repositories are the primary read abstraction. $manager->getRepository(Product::class) returns a repository with find($id), findBy(array), findOneBy(array), count(), and scan() for cursor iteration. For anything beyond trivial filters, use the DSL instead:

use ONGR\ElasticsearchDSL\Search;
use ONGR\ElasticsearchDSL\Query\FullText\MatchQuery;
use ONGR\ElasticsearchDSL\Query\Compound\BoolQuery;

$search = new Search();
$search->addQuery(new MatchQuery('title', $term));
$search->addQuery(new BoolQuery([...]));
$search->setSize(20)->setFrom(0);

$results = $manager->getRepository(Product::class)->execute($search);
// $results['hits']['hits'][...]['_source'] or iterating documents

Custom repositories for domain queries. Extend AbstractRepository (or implement the repository interface) and point your @ES\Document annotation at it, then expose named methods like findActiveBySku(). This keeps raw Search objects out of controllers and is the single biggest maintainability win in a legacy ONGR codebase.

Bulk indexing is the default write path. persist() stages documents and commit() flushes them. Do not call commit() inside a loop — stage everything, commit once. For imports, use the console commands (ongr:es:index:import, ongr:es:index:export) or $manager->bulk($docs) for very large batches.

Index lifecycle as a deploy step. Treat index creation as infrastructure, not application code. Scripts should run ongr:es:index:drop --force, then ongr:es:index:create, then re-import if the mapping changed. Mapping changes are not applied automatically to existing indices — this is the number one operational trap.

Services can be autowired by interface. The manager is available as ongr_elasticsearch.manager; inject it directly rather than reaching into the container. In a Symfony 3.4+ project you can alias it in services.yml.

Testing pattern. Point the test environment at a dedicated index name (config already interpolates %kernel.environment%) and reset the index in setUpBeforeClass(). Do not share the dev index with tests — the bundle has no transaction/rollback concept.

Profiler and debugging. The bundle ships a Symfony profiler panel showing queries and timings in dev. If queries look slow, check it before blaming the DSL — a missing keyword mapping is the usual culprit.

Extension points worth knowing exist. If the package's built-in behaviour doesn't fit, look at the Event classes — the bundle dispatches events around indexing and search that you can subscribe to for logging or post-processing. The connection is also configurable per-index, so you can route reads and writes to different clusters in constrained environments.

Gotchas and Tips

  • Dead end for current stacks. This is a 2017 fork with no dependents. It will not run on modern PHP (8.1+) or Symfony 5+/6+, and it will not talk to Elasticsearch 7.x/8.x in any compatible way. Adopt it only for maintenance of an existing installation, and budget for a migration rather than new features.

  • Mapping drift is silent. Adding a property to your document annotation does nothing until you rebuild the index. ongr:es:index:create on an existing index will not update mappings. Establish a drop → create → import workflow early.

  • Field types must match your query type. Annotating a field as text but querying it with a term query returns zero hits (due to the analyser), and vice versa. Use keyword for exact-match/filter/aggregation fields and text for full-text search; annotate both when you need both.

  • commit() is per-index, not global. Passing an index name to commit() scopes the flush. Calling commit() with no argument flushes all configured indexes, which is usually what you want in CLI scripts but not in request handlers.

  • Config cache and annotation reader. In dev, changes to document annotations require clearing the cache (bin/cache:clear) because the annotation metadata is cached. This is not always obvious and wastes debugging time.

  • Console command names vary by version. ongr:es:index:create in the 5.x line was ongr:es:index:update / similar earlier. Run bin/console list ongr to confirm what your pinned version actually exposes before scripting deploys.

  • No transactions, no rollback. Elasticsearch indexing is not transactional and the bundle doesn't try to be. If a document fails validation mid-bulk, the rest of the batch may still be indexed. Validate on the application side before persist().

  • Connection failures surface as cryptic exceptions. A wrong hosts value produces a client-level connection error deep in elasticsearch/elasticsearch, not a friendly bundle message. Test the host/port with curl before investigating the bundle.

  • Debugging by dumping the DSL. When a query returns nothing, echo $search->toJson() and hit the cluster with it directly. This isolates whether the problem is your query or the bundle's document hydration.

  • Hydration surprises. Documents are hydrated via reflection into the public properties on your annotated class. If you add constructor parameters or typed properties later, hydration can fail silently or throw confusing errors. Keep document classes plain.

  • Pin everything. With no maintainer and zero community usage, you'll be the first to hit any regression. Commit a composer.lock and consider vendoring the bundle fork locally if you need to patch the client version constraints.

  • Have a migration plan. Because no one is maintaining this, the reasonable long-term move is to migrate to elasticsearch/elasticsearch's own Symfony integration (or a modern maintained bundle) and port document annotations to explicit index templates. The annotation layer is the only thing you'd genuinely miss.

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.
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core
nodisrupt/laravel-agent
sierratecnologia/media-manager