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

Yetisearch Laravel Package

yetidevworks/yetisearch

YetiSearch is a Laravel package that brings fast, flexible full-text search to your Eloquent models. Index records, run relevance-ranked queries, apply filters, and paginate results through a simple, expressive API—no external search service required.

View on GitHub
Deep Wiki
Context7

Product Decisions This Supports

  • Build vs. buy for search: This package is the "build on SQLite" lane — no search cluster, no per-document billing, no network hop, and search state lives in the same SQLite database as the app's data. 2.6.1 tightens exactly the areas that make embedded search a defensible buy-in (index integrity, transactional writes, document lifecycle), which strengthens the case for keeping search in-house for single-node or low-to-mid-scale deployments.
  • Ship language-aware search UX: YetiSearch::stemmingFor($index) makes stemming a first-class, queryable property rather than a config detail. This unlocks user-facing decisions that previously required reading config files: labeling results ("Searching in French"), routing a query to a locale-specific index, warning users when a language has no stemmer (returned lower-cased, as given), or suppressing "stemmed match" affordances when null is returned. It also cleanly degrades: storages that don't implement ProvidesStemming return null rather than throwing, so multi-storage deployments don't need special-casing.
  • Upgrade urgency becomes a product decision, not just a chore: 2.5.x indexes written with the rebuildFts() path tokenized raw JSON, so field names (title, content, route, …) became searchable words in every document. That is a user-visible correctness bug — searching "content" returns the entire corpus. 2.6.1 self-heals on first write, which means we can ship the upgrade without a coordinated maintenance window or a bespoke repair script.
  • Editing and long-form content workflows are now trustworthy: Re-indexing a document with shorter content previously left orphaned {id}#chunk{N} rows searchable, so a word removed from a document still surfaced it. Any product with editable documents, versioned content, or chunked ingestion (transcripts, PDFs, long articles) was silently returning stale hits. 2.6.1 removes stale chunks in the same transaction as the write — a failed write keeps them, so there is no window of inconsistency.
  • Batch ingestion semantics are now well-defined: A batch that repeats an id previously persisted chunks from the earlier variant. Batches now write only the last group per id. This removes a class of "why is this document twice as long as it should be" defects from any import, sync, or re-index pipeline.
  • Safe composition with application transactions: insert(), insertBatch(), update(), delete(), and deleteByIdPrefix() now join an open caller transaction via savepoints instead of nesting their own. This is the enabler for "create the record and index it" as a single atomic unit — a real architectural decision (denormalized write-through indexing) that previously forced either no transactions or manual orchestration. Failure isolation is now correct too: a failed index write rolls back only the index write, not the caller's surrounding work.
  • Feature-flag decisions get cheaper: Indexes built with enable_spatial => false could not delete documents at all in 2.5.6/2.6.0 — delete() and deleteByIdPrefix() threw no such table: {index}_spatial (or {index}_id_map for own-content indexes). If we disabled spatial search to save space, document deletion was simply broken. This is a "must upgrade to keep the feature flag viable" item, and it also covers hand-dropped spatial tables, which matters for on-call recovery.
  • Concurrency story is now defensible in a pitch: The self-heal rebuild takes the write lock inside a transaction, re-checks the key, and fails the write rather than proceeding into a damaged state if it cannot get the lock. Multiple processes converge instead of racing. A process that reads the key drops its cached knowledge when another connection commits, so an index left unhealed by another process is repaired by the next write. That is an operational property we can actually write down.
  • Roadmap signal: The package is investing in correctness and introspection over new query features. If the roadmap depends on faceting, relevance tuning, typo tolerance at scale, or multi-tenant index isolation, those are not arriving here — plan accordingly.

When to Consider This Package

Adopt (or upgrade to 2.6.1) when:

  • The application already runs on SQLite and search scope is bounded — a few million documents or fewer, single-node or read-mostly, with predictable write volume.
  • You want search to be transactional with your domain writes. The savepoint behavior added in 2.6.1 is the concrete capability; if "create record + index it atomically" is a requirement, this is the version that makes it real.
  • You have editable or re-ingested documents with chunking enabled. The stale-chunk fixes are the difference between a correct index and one that quietly serves removed content.
  • You need per-index language behavior surfaced to the UI, or you operate multi-locale content sets with separate indexes and want stemming discoverable at runtime.
  • You run (or intend to run) with enable_spatial => false, or you support self-managed deployments where tables may be dropped manually — 2.6.1 is effectively required.
  • You are currently on 2.5.x. The corrupted-token state heals on first write, so the upgrade path is low-ceremony; but see the caveats below.

Look elsewhere when:

  • You need horizontal scale, replicas, or a dedicated search tier — SQLite's single-writer model is the ceiling, and no amount of transactional hardening changes that.
  • You need relevance tuning, custom analyzers beyond the bundled stemmers (English, French, German, Spanish), synonyms, faceting, or vector/hybrid retrieval. stemmingFor() is introspection, not an analyzer plugin system.
  • You have read-only or read-replica deployments that will never take a write. The self-heal runs on write only — "searches never do it" — so 2.5.x-corrupted indexes on a read-only path will keep returning garbage until something writes.
  • Your deployment was built by re-running deleteByIdPrefix() tooling against the same database after 2.5.x. That operation re-introduces the field-name corruption, and the key cannot detect it. Audit any operational runbooks before assuming the upgrade fixes existing state.
  • You use YetiSearch Pro — note that Pro marks its tables with its own yetisearch_pro_fts_built key, untouched by this release, so verify Pro compatibility independently rather than assuming 2.6.1 covers it.
  • You rely on the 2.6.0 guidance to run rebuildFts() once after prefix deletes on external-content indexes — 2.6.1 supersedes that advice, so any documentation, runbook, or migration step referencing it should be considered stale.

Adoption criteria that should gate the rollout:

  • Confirm no open caller transactions wrap index writes expecting the old nesting behavior — the semantics changed from "throws There is already an active transaction" to "join via savepoint," which is strictly better but is a behavior change worth noting in release comms.
  • Note the one known limit: a write made inside a caller transaction does its rebuild inside that transaction and remembers nothing, so a caller rollback means the next write heals again. That is deliberate and safe, but it means heal-on-first-write is not a one-time, fire-and-forget cost if writes are transactional.
  • Confirm the {index}_meta table exists on any index you expect to heal. An index with no meta table "does not say how it is stored" and is left to createIndex() — those will not self-heal.

How to Pitch It (Stakeholders)

One-liner: A hardening release. 2.6.1 makes our embedded search index self-repairing, safe to write inside application transactions, and correct when documents are edited or re-ingested — with no new infrastructure and no manual repair step.

For executives: This is a risk-reduction release on a component we depend on. It closes three user-visible correctness bugs — field names leaking into search results, deleted text still matching documents, and document deletion being entirely broken when spatial search is disabled — and it removes a maintenance window from the upgrade path because indexes repair themselves on first write. It also unlocks a small but visible product win: search can now tell the UI which language an index is stemmed in, and degrade gracefully when it isn't. No new services, no new vendors, no cost line change.

For engineering: Upgrade straight to 2.6.1, not 2.6.0. Highlights: (1) External-content indexes inherit a self-healing rebuild driven by an fts_built_by key in {index}_meta, run under the write lock in a transaction, re-checked after lock acquisition, rolled back cleanly on failure, with no-op behavior when the key is already set — and no rebuild on read paths. (2) Stale chunks are removed on rewrite via an indexed id range (id >= '{id}#chunk' AND id < '{id}#chunl'), not LIKE, so it is safe against ids containing #chunk, _, and %, and it covers all three storage layouts. (3) Batch calls dedupe repeated ids, keeping the last group. (4) insert/insertBatch/update/delete/deleteByIdPrefix join an open caller transaction with a savepoint instead of throwing and rolling back the caller's work. (5) Delete paths share one routine that skips missing tables, fixing spatial-disabled and own-content indexes with no {index}_id_map.

Caveats to state plainly: The self-heal only fires on write; read-only deployments keep any pre-existing corruption. Re-running 2.5.x deleteByIdPrefix() tooling against the same database reintroduces the corruption and the key cannot detect it — audit runbooks. The 2.6.0 advice to run rebuildFts() once after prefix deletes is superseded. YetiSearch Pro uses a separate key and needs independent verification. And the underlying constraint is unchanged: this is single-node SQLite search, not a horizontally scalable search tier — if scale or relevance tuning enters the roadmap, the build-vs-buy question reopens regardless of how solid 2.6.1 is.

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