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 Full Text Postgres Laravel Package

vertigolabs/doctrine-full-text-postgres

Adds PostgreSQL full-text search support to Doctrine, letting you index and query text columns with tsvector/tsquery for fast, relevance-ranked searching in Laravel and PHP applications without external search services.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. The package is a Doctrine DBAL/ORM extension, not an Eloquent package. It supplies custom DBAL types (tsvector, tsquery) and DQL functions (to_tsvector, to_tsquery, plainto_tsquery, ts_rank, etc.) so that PostgreSQL full-text search can be expressed inside Doctrine DQL rather than raw SQL. In a standard Laravel application — which is Eloquent-first — this is a foreign-body fit. It only becomes architecturally natural if the application already runs Doctrine through laravel-doctrine/orm (the Laravel Doctrine bridge) or is a Symfony application. The package itself is small: it is essentially a registration layer over Postgres primitives, which is an asset for risk (easy to fork) and a liability for value (thin wrapper around what the DB already does).

Integration feasibility. Feasible but conditional. Requirements: PostgreSQL as the primary datastore, Doctrine DBAL/ORM in the stack, and a willingness to register custom DQL functions and types in Doctrine configuration. For an Eloquent codebase, the cost is disproportionate: you would be introducing a second ORM (or at least a second persistence abstraction) to gain a query ergonomic that Laravel already provides. Laravel 9+ ships whereFullText() with PostgreSQL support, which covers the common to_tsvector @@ to_tsquery case natively. The package's incremental value over that is typed hydration and DQL composability, not raw capability.

Technical risk. High on maintenance, moderate on compatibility.

  • Last release 2021-10-04; 17 stars; zero dependents on Packagist. This is a single-maintainer, effectively dormant project — bus factor of one.
  • DBAL 3.x/4.x and PHP 8.1+ compatibility is unverified and likely the first breakage point; custom DBAL types are exactly the surface that churns between major versions.
  • The underlying Postgres feature (tsvector, tsquery, GIN indexes, text search dictionaries) is stable and well-documented, so the concept is durable even if the package is not.
  • Small code surface means a fork-and-vendor escape hatch is realistic (a few hundred lines), which materially de-risks the dependency.

Key questions for the team.

  1. Is the target application already on Doctrine, or is this being considered for an Eloquent codebase? (If Eloquent: stop, use whereFullText + GIN index.)
  2. Which doctrine/dbal and doctrine/orm majors are in the lockfile, and does the package's constraint allow them?
  3. Which PostgreSQL major version, and is a specific text-search configuration (language dictionary, weights A–D, unaccent) required?
  4. What is the ranking requirement — ts_rank, ts_rank_cd, or custom weighting — and does the package expose it or do we drop to raw SQL anyway?
  5. Who owns the fork if the maintainer goes silent?

Integration Approach

Stack fit. Two viable postures:

  • Fit: Laravel + Laravel Doctrine (or Symfony) + PostgreSQL. The package slots in as a Doctrine extension and pays for itself immediately.
  • Non-fit: Laravel + Eloquent + PostgreSQL. Use whereFullText(), a generated tsvector column, and a GIN index. Reaching for this package here adds an ORM and a dormant dependency to solve a problem Laravel already solves.

Migration path (assuming the Doctrine posture).

  1. Register the DBAL types (tsvector, tsquery) and DQL functions in the Doctrine configuration (e.g. config/doctrine.php under custom_string_functions / custom_numeric_functions / types).
  2. Add a search_vector column via migration (tsvector), populated by trigger or generated column, with a GIN index.
  3. Backfill and validate with to_tsvector('english', body) against a sample corpus.
  4. Expose search through a repository method that composes the DQL functions, keeping raw SQL out of controllers.

Compatibility. Verify three gates before committing: package constraint vs. locked DBAL/ORM majors, PHP version support (8.1/8.2/8.3), and Laravel/Symfony framework version. Given the 2021 release date, expect to pin versions or patch the package's composer.json. Test hydration of tsvector fields explicitly — typed conversion is the most fragile seam.

Sequencing. Run as a time-boxed spike on a branch before committing: (a) prove type/function registration works on the current lockfile, (b) benchmark query plans with EXPLAIN ANALYZE on realistic data volume, (c) compare effort against native whereFullText and against a pure raw-SQL repository method. Decide build-vs-buy-vs-fork at the end of the spike. If the spike shows friction, the fallback — a handful of raw SQL calls wrapped in a repository — is genuinely cheap.

Operational Impact

Maintenance. The dominant operational fact: the package is unmaintained. Treat it as vendored code from day one — fork it into the org, tag a version, and own it. The surface is small enough that this is hours, not weeks, but it must be an explicit decision, not a drift into "we'll deal with it later." Budget a review each time DBAL or PHP majors bump.

Support. Community support is effectively nil: 17 stars, no dependents, last release 2021. Internal expertise is the only support channel. Document the DQL functions and index strategy in the repo so the knowledge is not held by one engineer.

Scaling. PostgreSQL FTS scales well within a single primary: GIN indexes handle millions of rows competently, read replicas serve search reads fine. Watch write amplification — tsvector recomputation and GIN index maintenance add cost to every insert/update of the indexed columns. If search volume or corpus size outgrows single-node Postgres, the exit is to a dedicated search engine (OpenSearch/Meilisearch/Typesense); this package does not abstract that path, so plan the repository boundary to make the swap survivable.

Failure modes.

  • DBAL major bump silently breaks custom types → hydration errors or runtime exceptions on search queries.
  • Missing or wrong GIN index → sequential scans; search latency degrades non-linearly with corpus growth.
  • Dictionary/config change (e.g. adding unaccent, switching language) → existing search_vector values become stale until reindexed; requires a coordinated reindex window.
  • Ranking surprises: ts_rank output is not intuitive and must be tuned against real queries; users will notice relevance regressions.
  • Unparameterized to_tsquery composition → injection or syntax errors on user input; prefer plainto_tsquery/websearch_to_tsquery at the boundary.

Ramp-up. Engineers must learn both Doctrine DQL and Postgres FTS semantics (dictionaries, weights, ranking). For an Eloquent-only team this is a real onboarding cost with little transferable payoff. For a team already on Doctrine, it is a day of reading docs plus a spike. Factor ramp-up into the build-vs-buy call: native whereFullText plus a GIN index gets an Eloquent team to working search in an afternoon, which is very likely the better TPM recommendation despite the package's conceptual neatness.

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.
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle
adachsoft/api-version-bundle
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
cgv/localized-resource