whatwedo/search-bundle
whatwedo/search-bundle adds configurable full-text search to Symfony applications. It indexes Doctrine entities, supports filters and pagination, and returns relevance-ranked results so you can build fast search pages and list views with minimal setup.
Architecture fit. The headline framing needs correcting before any decision: whatwedo/search-bundle is a Symfony bundle built on Doctrine ORM, not a Laravel package. It delivers full-text search by pushing matching down to the relational database (native MATCH … AGAINST / tsvector style capabilities plus a maintained index table) rather than adding a sidecar service. For a Symfony + Doctrine codebase this is a strong architectural fit — no new infrastructure, no data duplication into a third-party cluster, no operational surface beyond the database you already run. For a Laravel/Eloquent codebase it is effectively a non-starter without a Doctrine bridge, which itself is an architectural change far larger than the search feature.
Integration feasibility. The surface area is small and idiomatic: annotate/attribute entities as searchable, let Doctrine lifecycle listeners keep an index table current, and expose a query API plus console commands for (re)indexing. That is a well-understood shape for a Symfony team and should be a days-not-weeks integration for a single bounded context. Feasibility is gated almost entirely on how cleanly the target entities map to a single searchable projection.
Technical risk.
DQL UPDATE/DELETE, raw SQL, fixture loads, and out-of-band migrations — the classic stale-index trap.Key questions.
Stack fit. Go/no-go hinges on the framework: Symfony + Doctrine → viable, low-friction. Laravel/Eloquent or a mixed stack → do not proceed; evaluate Laravel Scout with a database driver, TNTSearch, or a managed search service instead. If the estate is polyglot, scope this to the Symfony services only and accept a second, divergent search pattern.
Migration path. Prefer an additive, strangler-style adoption: introduce the bundle behind a thin SearchService interface owned by our domain, with the bundle as the first implementation. Existing LIKE-based or manual query code stays in place until the new path is benchmarked against it. This makes the eventual swap to Meilisearch/OpenSearch/Elastic a contained change rather than a refactor, and directly neutralises the continuity risk.
Compatibility. Verify three axes before committing: framework/PHP version alignment with our support window; Doctrine ORM 2.x vs 3.x (attributes vs annotations, event API changes); and database platform parity across dev, CI, and production — including collation and full-text configuration drift. Also confirm the index table DDL ships as a Doctrine migration we can own, since our schema pipeline must be the source of truth.
Sequencing.
SearchService with the bundle behind it, plus a feature flag.Maintenance. Low code churn means low ongoing effort, but also low upstream responsiveness. Budget for periodic upstream triage and assume we may need to patch. Plan the fork posture now: vendor the package, or maintain a maintained-fork branch with our own CI. Because the package's correctness depends on DB behaviour, our test suite must cover search semantics per supported engine, not just unit-level logic.
Support. No commercial backing, no SLA, community-only help. That is acceptable for internal/admin tooling and unacceptable for a revenue-path feature unless the wrapper abstraction is in place and a swap is pre-designed. Document the escape hatch (target engine, data export path, expected effort) before launch.
Scaling. The database does the work: index size and write amplification scale with the number of searchable entities and the frequency of writes, since each persisted entity touches the index. Read scaling is bounded by the primary's capacity or read replicas — replica-based search raises freshness questions (replication lag versus index lag). Reindex jobs on large tables are the practical ceiling: they are I/O-heavy, may hold locks, and should run batched, off-peak, and resumable. If search QPS ever rivals transactional QPS, this design should be replaced rather than tuned.
Failure modes.
Ramp-up. The learning curve is shallow for developers already fluent in Doctrine events and Symfony DI, and the API is small enough that a mid-level engineer is productive in a day. The real ramp-up cost sits with operators, not developers: SRE/on-call needs runbooks for reindex, staleness detection, and failure recovery, and the team must understand that "search is down" here means "the database is slow," which changes the incident playbook.
TPM recommendation. Low-adoption, single-maintainer, database-native search is a reasonable fit for internal or secondary search in a Symfony/Doctrine estate, provided it is wrapped behind an owned interface and launched with reconciliation and golden-query tests. It is not appropriate as the sole search dependency for a customer-facing discovery experience, and it is out of scope entirely for a Laravel/Eloquent stack.
How can I help you explore Laravel packages today?