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

Admin Search Bundle Laravel Package

sonata-project/admin-search-bundle

Sonata Admin Search Bundle adds unified search to Sonata Admin: index configured entities, query records from one search page, and get grouped, permission-aware results with direct links to edit screens. Ideal for quickly locating content across large Symfony backends.

View on GitHub
Deep Wiki
Context7

Getting Started

Given the package is archived and its last release was January 2021, treat "getting started" as an evaluation exercise first: confirm it still installs and boots against your Symfony/Sonata Admin version before you write any application code around it.

Minimal steps:

  1. Install and inspect before committing. Add it via Composer (composer require sonata-project/admin-search-bundle) in a throwaway branch, then open the vendor directory and read the bundle's DependencyInjection/Configuration.php, its services file, and any Admin/*Interface classes. Those three files tell you the entire integration surface: what config keys exist, what service IDs you can override, and which interface your admin must implement to become "searchable." Do this first — the documentation for a 2021 abandoned bundle will lag reality, and the source is the only reliable spec.
  2. Stand up Elasticsearch with the right version. Check the package's composer.json for the Elasticsearch client/Elastica version it pins and match your server accordingly. This bundle predates Elasticsearch 7's removal of mapping types, so expect it to target ES 5.x/6.x. Running a modern ES against it will not work.
  3. Register the bundle in config/bundles.php (or AppKernel), and add the required config block (Elasticsearch host/index name, and whatever indexing strategy it supports).
  4. Make one admin searchable. The typical first use case: you have a Sonata Admin entity with a huge table that is slow to filter with Doctrine LIKE queries. Mark that admin as searchable (via the bundle's interface/trait, per the source you read in step 1), define a minimal index mapping for the fields you want searchable, and index a small fixture set with whatever console command the bundle registers (bin/console list sonata:admin-search or similar).
  5. Verify end-to-end by loading that admin's list view and confirming results come from Elasticsearch rather than the ORM. Turn on the ES slow log or query log for this first test — it's the fastest way to confirm the bundle is actually querying ES and not silently falling back.

Do not plan a rollout until steps 1–5 pass. With 0 dependents and a 2019-era codebase, the most likely outcome is that it fails on install against a current Sonata Admin, and your "getting started" ends at a decision to reimplement the small amount of glue yourself.

Implementation Patterns

The bundle is thin glue: it lets a Sonata Admin listing delegate its query to Elasticsearch instead of the Doctrine model manager. The patterns below are the ones a day-to-day developer would actually build on top of it.

Index definition per admin. Keep one index (or one type) per searchable entity, with a mapping that mirrors only the fields you filter/sort/search on. Resist indexing the whole entity — it inflates index size, forces a reindex on every schema change, and makes mapping drift more likely. Define the mapping in config or a dedicated class, not inline in the admin.

Indexing on writes. The bundle likely offers a Doctrine event subscriber or a manual index() call. For anything beyond a demo, prefer explicit indexing from your service/domain layer over the bundle's automatic subscribers: you control transaction boundaries, you can batch, and you avoid indexing half-written entities. If you do use automatic listeners, make sure they run after the flush completes, not before.

Bulk reindex command. You will reindex constantly — after mapping changes, after backfills, after ES restarts on a dev machine. Wrap the bundle's indexing in your own console command that pages through entities in batches (500–1000 at a time), uses the Elasticsearch bulk API, and is idempotent. This command is the single most valuable piece of code you'll write around this package, and it survives even if you later drop the bundle.

Admin integration. Point the admin's list query at the search service rather than the default ModelManager. The usual shape is to override configureQuery/createQuery (or the datagrid's data source) so the filtered, paginated, sorted result set comes from ES. Keep the same filtering interface Sonata exposes, so admins and users don't notice the difference — the goal is a drop-in replacement for the list view.

Search result → entity hydration. ES returns IDs; you then findBy(['id' => $ids]) via Doctrine and re-order in PHP to match ES relevance/order. Watch the classic N+1: hydrate in one query and reorder in memory, never loop find() per hit.

Fallback path. Always keep the Doctrine query path available behind a feature flag. When ES is down or the index is stale, an admin backend that 500s is worse than a slow one. A try/catch that logs and falls back to the ORM listing is cheap insurance.

Reuse across admins. Put the mapping, indexer, and search-query builder behind your own small service layer (EntityIndexer, SearchQueryBuilder) that wraps the bundle. If the bundle needs replacing, you swap one implementation, not every admin.

Gotchas and Tips

It is archived — assume no upstream fixes. No PHP 8.x or Symfony 5/6 support is guaranteed, and the pinned Elasticsearch client will be old. Before writing integration code, run composer why-not against your Symfony/Sonata versions and check whether it even resolves. If it drags in a conflict, the honest move is to lift the ~200 lines of ES glue you need rather than pin your whole stack backward.

Elasticsearch version mismatch is the #1 failure mode. This bundle targets an Elasticsearch generation that still uses mapping types (_type) and a pre-7.x query DSL. Running it against ES 7/8 will produce deprecation errors at best and silent wrong results at worst. Pin the ES server version explicitly in docker-compose/CI, and never let a cloud-managed ES "latest" drift under a production deploy.

Index drift and stale mappings. ES will not let you change an existing field's mapping in place. Every mapping change means: create new index with an alias, reindex, flip the alias. Build this alias workflow on day one — retrofitting it after your first "why is this filter wrong" incident is painful.

Indexing lag after writes. Even if the bundle indexes on flush, ES refresh is near-real-time (~1s by default, or per refresh_interval). Tests and "I saved it but it's not in search" bug reports both stem from this. Use refresh=wait_for (or an explicit refresh) in tests, and document the lag for your users.

Silent partial failures. Bulk indexing returns per-document errors with a 200 at the HTTP level. Check the errors flag and the per-item status in your reindex command, or you'll "successfully" index 90% of a table and not notice.

Memory during bulk reindex. Do not build one giant array of documents. Stream with Doctrine's iterate()/toIterable() in batches and clear the EntityManager between batches. Otherwise a 1M-row backfill will OOM the worker.

Configuration quirks. Bundle config defaults may point at localhost:9200 with no auth and no timeout. Set the host, credentials, and a sane timeout explicitly — a hanging ES connection will hang your admin UI, and the default client timeout is often too long for a web request. Also check whether the bundle assumes a single index name globally; multi-entity apps usually need per-admin index config, which may require overriding services.

Extension points to prefer. Override the bundle's search service and indexing subscriber via DI service decoration rather than editing vendor code or subclassing the admin heavily. Decorating your own thin wrapper around the bundle's service keeps the swap-out path clean and gives you one place to add logging, metrics (query latency, index size), and the fallback-to-ORM behavior.

Testing. Integration-test against a real ES container (Testcontainers or a docker-compose fixture), not a mock — the failure modes here are all in the mapping/query/refresh layer, which mocks hide. Keep a small fixture index and one test per searchable admin that asserts both the happy path and the fallback path.

Bottom line for day-to-day leverage: use this package as a reference implementation, wrap it tightly, and make your own bulk-reindex command and fallback the load-bearing parts. Do not put it on the critical path of a new project without budgeting for its replacement.

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.
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin