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

Postgres Search Bundle Laravel Package

gkovrey/postgres-search-bundle

gkovrey/postgres-search-bundle integrates PostgreSQL full-text search into Symfony/PHP applications, offering database-native indexing and query support for fast, relevant search results without an external search engine. Configurable, lightweight, and easy to wire into existing projects.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit — poor, and not in the way the brief assumes. The package is a Symfony2 bundle, not a Laravel package. It ships a *Bundle class, a DependencyInjection/ extension, and Symfony Resources/config/services.yml wiring. Laravel's service container has no concept of bundles, so nothing loads: no service provider, no auto-discovery, no config merge. Beyond packaging, the bundle's real functionality (Doctrine 2 DQL custom functions and schema/listener hooks) is bound to the Doctrine ORM persistence layer, while Laravel defaults to Eloquent. Two independent mismatches — framework and ORM — must both be resolved before a single line of value is delivered.

Integration feasibility — effectively zero without a rewrite. Composer resolution will fail on any current Laravel (10/11) project. Expect hard conflicts on symfony/* (bundle requires 2.x, Laravel 11 requires 6/7), doctrine/orm (~2.2–2.4 vs current 2.19+/3.x), and PHP platform constraints (package era implies PHP 5.x/7.0; Laravel 11 requires 8.2+). The useful surface area is narrow: DQL functions wrapping to_tsvector / plainto_tsquery / ts_rank, plus index DDL helpers. That is reimplementable in a Laravel app in roughly a day of engineering — the bundle is cheaper to understand than to install.

Technical risk — high, in every dimension.

Risk Assessment
Maintenance Last release 2016-09-06. ~9 years unmaintained. Abandoned in practice.
Adoption signal 0 stars, 0 dependents. No external validation, no production usage evidence, no issue history to mine for known bugs.
Security No CVE response path, no maintainer to patch. Any transitive dependency it pins is frozen at 2016 vulnerability state.
Compatibility PHP 8.x incompatibilities highly likely (removed each(), create_function, old reflection APIs, Doctrine\Common\Persistence).
Correctness PostgreSQL FTS semantics (dictionaries, locale, weighting, ts_rank_cd normalization) are subtle; with no users, there is no bug-finding pressure on the implementation.
Licensing Verify LICENSE file before any procurement motion; unstated license on an abandoned repo is a legal blocker regardless of code quality.

Key questions for the team:

  1. Is the actual requirement "PostgreSQL full-text search," or "search on our Laravel app"? The former is a SQL/DB problem; the latter is a Laravel integration problem with better modern answers.
  2. Which persistence layer is mandated — Eloquent, or is Doctrine on the roadmap? If Eloquent, this package is irrelevant by construction.
  3. What is the real scope: tsvector columns + GIN index + ranking, or just substring/prefix matching that pg_trgm or LIKE handles?
  4. Do we need multilingual stemming, weighted fields, or highlighted snippets (ts_headline)? These drive build effort, not package choice.
  5. Who owns search long-term — application team or DBA?

Recommendation: Do not adopt. Treat the repository as reference material, not a dependency.

Integration Approach

Stack fit — none. The fit matrix is a hard fail on framework (Symfony2 ≠ Laravel) and a soft fail on ORM (Doctrine ≠ Eloquent). Even in a hypothetical Symfony shop, Symfony 2.x has been EOL since 2018 and the bundle targets an ORM generation now three majors behind. There is no version of a current PHP stack where this installs cleanly.

Migration path — reimplement the pattern natively, in three steps. The bundle's value is a set of idioms, and those idioms transfer to Laravel cleanly:

  1. Schema layer. Add a generated/maintained tsvector column and a GIN index via a Laravel migration using DB::statement:
    DB::statement("ALTER TABLE documents ADD COLUMN search_vector tsvector
        GENERATED ALWAYS AS (to_tsvector('english', coalesce(title,'') || ' ' || coalesce(body,''))) STORED");
    DB::statement("CREATE INDEX documents_search_idx ON documents USING GIN (search_vector)");
    
    Generated columns (Postgres 12+) eliminate the trigger-maintenance problem the 2016 bundle solved with listeners — a material simplification.
  2. Query layer. Wrap search in an Eloquent local scope or query object emitting whereRaw("search_vector @@ plainto_tsquery(?, ?)", [...]) with ts_rank_cd ordering. Keep it in one class so the SQL dialect is not leaked across the app.
  3. Abstraction layer. Expose Search::documents($term) behind an interface so a later move to Meilisearch/OpenSearch/Scout is a swap, not a rewrite. This is the decision that actually protects the roadmap.

Compatibility. Validate on the target stack before committing: PostgreSQL ≥ 12 (generated columns), PHP 8.2+, Laravel 10/11. Confirm unaccent and the relevant text_search_config dictionaries are installed on the target database — a frequent staging-to-prod surprise.

Sequencing.

  • Week 1 — Spike (2 days). Prototype the generated column + GIN index + ranked query against real data volume. Measure query latency and index build time at production row counts.
  • Week 1 — Decision gate. If the prototype meets relevance and latency targets, close the build-vs-buy question; the "buy" option is already eliminated.
  • Week 2 — Implement. Migration, query object, interface, feature tests including ranking assertions and empty/null-term behavior.
  • Week 3 — Harden. Slow-query review, index bloat check, VACUUM/autovacuum tuning on the target table, relevance tuning with real queries from product.
  • Later — Revisit. If requirements grow to faceting, typo tolerance, synonyms, or cross-entity search, that is a signal to move to a dedicated engine, not to extend raw SQL.

Alternative evaluation (short list). laravel/scout with a Postgres driver, or a maintained FTS package, if the team wants a dependency rather than in-house SQL. Either is a strictly better bet than a 2016 Symfony2 bundle, because both are installable, testable against your stack, and have a maintainer to escalate to.

Operational Impact

Maintenance — the dominant cost, and it is total. An unmaintained 2016 dependency means the team inherits the entire maintenance burden the moment it lands, plus the burden of the framework/ORM port. That is strictly worse than building the ~200 lines of SQL and query-object code yourself, which the team would own and understand either way. Cost of ownership: the package adds work relative to a native implementation.

Support — none exists. No maintainer SLA, no issue triage, no release cadence, no security disclosure channel. Escalation path is "read the source." With 0 dependents there is also no peer community to consult. In a procurement or architecture-review context this is an automatic finding: no viable support model.

Scaling — the Postgres side is fine; everything around it is not. PostgreSQL FTS with a GIN index scales well to tens of millions of rows for read-heavy search. Real constraints to plan for:

  • Write amplification. Every insert/update rebuilds the tsvector; on high-write tables this shows up as index maintenance cost. Partitioning or a narrower indexed field set mitigates.
  • Index bloat. GIN indexes accumulate dead tuples; autovacuum settings on the indexed table need explicit tuning.
  • Bloat on the row. A stored tsvector adds bytes per row; acceptable, but size it against the largest text columns.
  • Concurrency. FTS queries are read-only and cache-friendly; the risk is long-running ts_rank sorts over large result sets — bound with LIMIT and, if needed, ts_rank thresholds.

Failure modes to instrument before launch:

Failure Symptom Mitigation
Stale search_vector New/edited records invisible in search Generated column removes the class of bug entirely; if trigger-based, add a reconciliation job + drift check
Locale/dictionary mismatch Wrong stemming, missed matches for non-English content Pin text_search_config explicitly per column; test with production-language corpora
Missing unaccent extension Accented queries return nothing Provision extension in migrations, not manually
Unbounded ranking sort Slow queries under load LIMIT, pagination, EXPLAIN ANALYZE in CI against representative data
PHP 8 incompatibility (if adopted) Fatal errors on autoload or first call Eliminated by not adopting
Silent relevance regression Users report "search is bad" with no error signal Capture zero-result queries; add relevance test fixtures to CI

Ramp-up. Low for the native path — a mid-level Laravel engineer with basic Postgres familiarity can own it in under a week, and the SQL is legible to any DBA. High for the package path — the engineer must first learn Symfony2 bundle conventions and Doctrine 2 internals to port code that will then be thrown away. The ramp-up asymmetry alone justifies the build decision.

Bottom line for the product owner: the package scores 0.03 for good reasons. It is a 2016 Symfony2/Doctrine artifact with no maintainer, no users, and no installable path into a Laravel codebase. The correct move is to harvest its ideas — tsvector column, GIN index, ranked tsquery matching — into ~200 lines of first-party Laravel code behind a search interface, and reserve the dependency decision for the point where requirements genuinely exceed what PostgreSQL FTS can do. Budget one engineering week, not a migration project.

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.
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core