intaro/postgres-search-bundle
A Symfony bundle for integrating PostgreSQL native full-text search with Doctrine entities. It offers indexed tsvector support, search query helpers, and relevance ranking, helping applications avoid external search engines while using Postgres search features.
tsvector/tsquery and GIN indexes is the cheapest viable search tier: no new service, no data-sync pipeline, no second source of truth, and search results that are automatically consistent with your Doctrine/Eloquent entities. That comparison is worth running regardless of what you decide about the package itself.Consider it only if every one of the following holds:
tsvector columns rather than hand-written DQL.setweight/ts_rank). No faceting, no typo tolerance, no synonyms, no multilingual analyzer story.Look elsewhere if:
whereRaw("to_tsvector(...) @@ plainto_tsquery(?)") with bound parameters), a generated tsvector column plus GIN index migration, an Eloquent local scope or SearchRepository, or a maintained option — Laravel Scout with a Postgres-compatible driver — rather than a Symfony bundle.doctrine/dbal.Verdict: Not adoptable as a dependency. The pattern — PostgreSQL native full-text search — is worth a short design spike. This package is a reference implementation to read, not install.
To executives: We evaluated a package for adding full-text search on top of PostgreSQL. The strategic takeaway is favorable on cost: if our search needs are simple keyword matching, we can ship search on the database we already run — no new vendor contract, no new infrastructure, no new operational burden, no second copy of our data to keep in sync. That is a meaningful line-item saving versus managed search services, which typically run from hundreds to thousands of dollars per month before integration work, and versus self-hosted Elasticsearch, which carries real on-call cost.
The specific package reviewed, however, is not viable for our stack. It is a Symfony 2 bundle built for Doctrine 2 — Symfony 2 has been end-of-life since 2018 — and it has zero stars and zero dependents, meaning no community, no maintenance, and no security-patching path. Recommending it would introduce an unmaintained, unpatched dependency into our application in exchange for roughly a few days of code we can write and own ourselves. Recommendation: reject the package, retain the architectural option. Proceed with the PostgreSQL approach implemented natively in Laravel behind a thin, owned SearchService abstraction, and set a measurable trigger — p95 latency or relevance complaints — for revisiting a dedicated engine with real data rather than speculation.
To engineering: Don't take the dependency. Its value is a mapping layer over tsvector columns plus DQL helpers — a small surface we can replicate with a generated tsvector column (Postgres 12+), a GIN index migration, an Eloquent scope using parameterized to_tsvector/plainto_tsquery (or websearch_to_tsquery on 11+), and ts_rank_cd as a select alias for ordering. Treat the repository as a reference implementation: read it for SQL patterns, do not install it, and avoid copying source verbatim without checking its license — a clean reimplementation from documented PostgreSQL patterns avoids that obligation entirely. Flag for the spike: dictionary/regconfig selection (pin per column if multilingual), weight classes (title vs. body), index bloat and VACUUM/REINDEX hygiene, work_mem tuning under realistic load, and query-plan validation at production-like data volume. Add a fixed query corpus as a CI regression test so relevance degradation after Postgres upgrades is caught rather than discovered by users. If the spike shows requirements exceed Postgres FTS, fall back to Scout plus a dedicated driver — and we'll then have the latency and quality baselines needed to justify that spend.
How can I help you explore Laravel packages today?