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

Doctrine Solr Bundle Laravel Package

mdiyakov/doctrine-solr-bundle

Symfony bundle that integrates Apache Solr with Doctrine ORM entities, letting you index and search your database records through Solr. Provides entity mapping, automatic indexing, and query building for fast full-text search in Symfony applications.

View on GitHub
Deep Wiki
Context7

Getting Started

Reality check first. The bundle still targets Symfony 2/3 and its dependency graph is frozen in the 2018 era, despite the v1.1.1 patch (rollback wrapper, clean command, multi-EM support, manager unit tests). That patch is a maintenance bump, not a modernization — it does not add Symfony 4+ flex support, attribute mapping, or a current Solarium constraint. If you're on Symfony 4+/PHP 7.4+/modern Solr, assume it will not install cleanly and budget for a fork. If you're maintaining a legacy Symfony 2.8/3.x app talking to an older Solr, it remains a pragmatic way to get entity-backed search working — and v1.1.1 removes a couple of real sharp edges, so it's worth pinning to that tag rather than an older one.

Minimal path:

  1. Install and pin. Add mdiyakov/doctrine-solr-bundle at v1.1.1, and pin symfony/* and solarium/solarium to versions that existed in 2018. Verify the transitive dependency graph before letting Composer update anything else. If you were on an earlier tag, read the v1.1.1 diff — it touches the entity manager wiring, so your service definitions may need adjusting.
  2. Register the bundle in app/AppKernel.php (or config/bundles.php if you're on 3.4+) under the dev/prod environments you need.
  3. Configure the Solr connection(s) and entity manager(s). Check DependencyInjection/Configuration.php first; the config tree is the source of truth. v1.1.1 added multi-entity-manager support through Doctrine Registry, so expect a config key that lets you name which EM(s) to index rather than assuming doctrine.orm.default_entity_manager.
  4. Wire the wrapped entity manager. v1.1.1 introduces a wrapper around the EM so Solr changes can be rolled back when $em->flush() throws. Resolve EMs from the bundle's wrapper (or the Registry service) in your own code rather than the raw doctrine.orm.entity_manager alias — otherwise you lose the rollback behaviour.
  5. Annotate one entity as a Solr document — inspect Annotation/ for the exact names (@Solr\Document, @Solr\Id, @Solr\Field, and likely a type/transformer attribute). Start with one entity and 3–5 fields.
  6. Seed and reindex with the bundle's console commands (look in Command/). v1.1.1 ships a clean-all-Solr-data command alongside the index command — useful for a clean rebuild. Verify in the Solr admin UI (/solr/#/<core>/query) that documents landed.
  7. First use case: a simple full-text search endpoint — controller injects the bundle's search service, runs a query string against the core, returns entity IDs, hydrates via Doctrine. Highest-value, lowest-risk entry point.

Implementation Patterns

Annotation-driven mapping on entities. Mark an entity as a document, its ID field, then searchable/stored fields with their Solr type. Keeping mapping on the entity travels with the model but couples domain objects to a search concern; if that offends you, map a dedicated read-model/DTO entity instead.

Automatic sync via Doctrine events. The bundle registers a Doctrine event subscriber hooking postPersist, postUpdate, postRemove. This is the "it just works" path — but only for changes made through the ORM. Bulk DQL updates, raw SQL, and direct DB writes bypass it entirely.

Rollback-safe flush (new in v1.1.1). The new EM wrapper listens for exceptions thrown during $em->flush() — including from other EntityListeners — and rolls back the corresponding Solr mutations so the index doesn't drift from the DB when a transaction fails. Lean on it: inject your own services with the wrapped EM where indexing matters, and don't catch-and-swallow flush exceptions above it. Note it protects the index for that flush, not across requests; if Solr itself is down, behaviour is still whatever the listener does on transport failure (check EventListener/).

Multiple entity managers (new in v1.1.1). If you have more than one EM (e.g. a separate read/legacy connection), you can now register all of them via Doctrine Registry and index across them, rather than the bundle picking up only default. Bind each document type to an explicit EM + client name in config.

Manual indexing for bulk operations. For imports and seed data, disable auto-sync and run the console reindex in batches. A clean-then-rebuild cycle is now cleaner thanks to the clean command:

# destructive: wipes the core, then chunked rebuild
app/console doctrine:solr:clean --client=default
app/console doctrine:solr:index --entity=AppBundle:Product --offset=0 --limit=5000

Confirm whether the clean command prompts before deleting — treat it as a production hazard unless it does.

Search side: two-step query. Query Solr for IDs + scores, hydrate with findBy(['id' => $ids]), then re-sort in PHP to match Solr order. The bundle doesn't provide ODM-style entity hydration.

Related entities / denormalization. Foreign keys are useless in Solr. Use the field transformer/mapping hook to flatten related data (product.category.name) at index time; eager-join to avoid N+1 during reindex.

Multi-core setups. One client per core, each document type bound to its core. Keeps product and content search independent, and commit/reindex on one doesn't disturb the other.

Wrap search in a service. Introduce ProductSearchService owning query construction, pagination, facets, and ID→entity hydration. That's your seam for swapping the bundle out.

Gotchas and Tips

  • Maintenance is still the headline risk. v1.1.1 (rollback wrapper, clean command, manager tests, multi-EM) is a genuine improvement over 2018 and worth adopting, but it's a patch-level bump — no Symfony 4+/attribute/modern-Solarium work. Treat it as a vendored legacy dependency: fork into an internal package, freeze Solarium, document the fork point, and plan an exit (netlogix/solr or a thin Solarium integration) rather than a long-term commitment.
  • Wrapped EM vs raw EM. The rollback only works if you go through the wrapper/Registry. Any code resolving doctrine.orm.entity_manager directly, or using a third-party EM decorator, bypasses it. Audit your service definitions.
  • Rollback semantics are narrow. It undoes Solr changes for a failed flush, but does not give you distributed transactions. If Solr is unreachable at flush time you can still lose the index update or fail the DB transaction — check whether the listener swallows transport exceptions and add logging so drift is detectable. Indexing after commit via a queue is still the more robust pattern.
  • Clean command is destructive. It deletes all data in the core. Gate it to non-prod environments, or confirm it prompts, before exposing it in runbooks. Pair it with a rebuild step or you'll serve an empty index.
  • Multi-EM binding. With Registry support, mis-binding an entity to the wrong EM (or omitting one) means an entire model silently never gets indexed. Assert each document type maps to exactly one EM + client.
  • Annotation/Doctrine metadata caching. After editing annotations, cache:clear — stale metadata is the #1 cause of "my new field isn't in Solr."
  • Events don't fire on bulk ops. DQL UPDATE, INSERT ... SELECT, and migrations silently desync the index. Add a post-deploy reindex or a reconciliation job comparing DB and Solr counts.
  • Commit/visibility lag. Solr commit isn't immediate and looping commits is CPU-heavy. Batch add operations, commit once per batch.
  • Type mismatches are silent until query time. Solr is schema-driven; send a string to a pdate field and you get 400s at index time or silent filter failure. Align your schema with the bundle's field mappings before declaring success.
  • Debugging order: (1) query the Solr admin UI directly — confirm docs and fields exist; (2) enable Solarium's logger to inspect request/response bodies; (3) only then read EventListener/ and the new EM wrapper. Most bugs are Solr-side.
  • Config quirks. With multiple clients/EMs, the default binding is easy to mis-bind; reference explicit names everywhere rather than relying on default.
  • Extension points to lean on: field transformer/mapper classes (dates, enums, relations), the event listener (custom events, failure guards), the new EM wrapper (index/DB consistency), and the search service (facets/highlighting the bundle doesn't expose). This is where the bundle is thinnest and where most real work lands.
  • There are now unit tests for the managers — run them against your pinned dependency versions to verify the package still behaves before building on top; they're also the best documentation of the wrapper/Registry contracts.
  • Document your exit. Keep the integration confined to one service + one annotated entity set so a future migration to a maintained Solr bundle is a weekend, not a quarter.
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.
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect
youbar/easy-crud
c-point-labs/laravel-hostyourai
dbravoan/dbcms-admin-theme-dbcms
dbravoan/dbcms-theme-db-cyber
dbravoan/dbcms-blocks-basic
dbravoan/dbcms-module-content-audit
dbravoan/dbcms-module-ai-assistant
paygate-to/paygate-php
padosoft/askmydocs-connector-base
defstudio/supercharged-carbon
bernskioldmedia/laravel-matomo