fix(store): index BM25 on a search_text column carrying the abstract and summary layers - #998
Open
gorkem2020 wants to merge 1 commit into
Open
gorkem2020 wants to merge 1 commit into
gorkem2020 wants to merge 1 commit into
Conversation
…and summary layers The FTS index sat on the text column, which only holds the L0 abstract, so a keyword that survived only in the overview or the content layer was invisible to indexed full-text search. A search_text column now carries the abstract plus the summary layers, recomputed at one write boundary for every rewrite path; tables from before the column existed get it through the legacy-column migration (seeded, then backfilled from the metadata layers) and the index moves off the abstract column. A backfill-search-text CLI command is the repair path next to reindex-fts.
gorkem2020
force-pushed
the
fix/fts-index-search-text
branch
from
September 16, 2026 06:24
9c4918a to
e82a89d
Compare
gorkem2020
marked this pull request as ready for review
September 16, 2026 06:26
Contributor
Author
|
Ready for review. Rebased onto the current master (93899f88, post #946); only the two test-registration files conflicted (ordered union), the source is unchanged from the draft. Fleet evidence: this change has run on our gateway since 2026-09-12 (the store migration ran once on first start and backfilled |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes #913. The BM25 index sat on the
textcolumn, which only holds the L0 abstract, so a keyword that survived only in the overview or the content layer was invisible to indexed full-text search. The lexical scan did see those layers, but only when the indexed query returned nothing at all. The vector column already embeds the abstract plus the content and is untouched.Changes
src/search-text.ts(new):buildSearchText(text, metadata)joins the abstract with thel0_abstract,l1_overviewandl2_contentmetadata layers, folding identical layers once; missing or broken metadata degrades to the abstract.src/store.ts: newsearch_textcolumn and the FTS index now targets it. Every write path (store/bulkStore,upsert,importEntry,update,bulkUpdateExact, the recall-metadata merge, the legacy-scope repair,storeSuperseding) passes rows through onetoRowboundary that recomputes the column from the row's own text and metadata, so no rewrite path can let it drift. Tables from before the column existed get it through the existing legacy-column migration:addColumnsseeds it with the abstract, then the same locked step backfills it from the metadata layers.createFtsIndexmoves the index off the abstract column and drops the leftover index so a bare FTS query stays unambiguous;bm25Searchnames the column explicitly;rebuildFtsIndexrecreates on the current column. A store whose migration did not run keeps the previoustextindex (the column is resolved from the schema and the index list, never assumed).MemoryStore.backfillSearchText({ dryRun }): report or rewrite rows whose column is missing or stale. It checks out the latest table version first, so a CLI process sees the gateway's writes.cli.ts:memory-pro backfill-search-text(report only;--applyrewrites), the repair path next toreindex-fts.test/fts-search-text-column.test.mjscovers the builder, a content-only token found through the real index with the lexical fallback forbidden, the rewrite paths keeping the column current, a pre-upgrade table being migrated, backfilled and re-indexed on open, the backfill reporting and repairing a stale row, andreindex-ftsending with a single index onsearch_text.test/fts-index-fold.test.mjsand the CLI attachment test follow the column move. Registered in thenpm testchain and the CI manifest.Notes
addColumnsvalue expressions against existing columns only, so the schema step can seed the abstract but cannot parse the metadata JSON; the app-level backfill in the same migration step does that.mergeInsert(...).whenMatchedUpdateAll()source row that lacks the column keeps the target value, whileaddwithout it writes NULL; the write boundary sets the column on every path, so the behavior does not depend on either.entry.textkeeps returning the abstract; the new column is index plumbing only.Verification
npm run build,npm test(full chain), the new test file,fts-index-fold,store-lexical-metadata-search,cli-subcommand-attachment,redis-lock,migrate-legacy-schema,node scripts/verify-ci-test-manifest.mjs.