From fa214db367f4c4ee5da8d8421bbf73113e7bc84d Mon Sep 17 00:00:00 2001 From: Ryan Date: Tue, 24 Mar 2026 20:12:45 -0400 Subject: [PATCH] fix: correct BM25 field weights to include all 3 FTS columns The bm25() call only had 2 weights for 3 columns (filepath, title, body), giving body an implicit weight of 0. Add proper weights: filepath=1.5, title=4.0, body=1.0 so title matches are boosted and body content is scored. --- src/store.ts | 2 +- test/store.test.ts | 28 ++++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/store.ts b/src/store.ts index f17404d..5770107 100644 --- a/src/store.ts +++ b/src/store.ts @@ -2771,7 +2771,7 @@ export function searchFTS(db: Database, query: string, limit: number = 20, colle d.title, content.doc as body, d.hash, - bm25(documents_fts, 10.0, 1.0) as bm25_score + bm25(documents_fts, 1.5, 4.0, 1.0) as bm25_score FROM documents_fts f JOIN documents d ON d.id = f.rowid JOIN content ON content.hash = d.hash diff --git a/test/store.test.ts b/test/store.test.ts index c5755f8..a55996e 100644 --- a/test/store.test.ts +++ b/test/store.test.ts @@ -1203,6 +1203,34 @@ describe("FTS Search", () => { await cleanupTestDb(store); }); + test("searchFTS title boost outweighs higher body frequency", async () => { + const store = await createTestStore(); + const collectionName = await createTestCollection(); + + // Document with "quantum" mentioned in a longer body but NOT in the title + await insertTestDocument(store.db, collectionName, { + name: "body-only", + title: "General Science Notes", + body: "This research paper discusses quantum mechanics and the quantum model of computation. The quantum approach offers improvements over classical methods.", + displayPath: "test/body-only.md", + }); + + // Document with "quantum" in the title but a shorter body mention + await insertTestDocument(store.db, collectionName, { + name: "title-match", + title: "Quantum Computing Overview", + body: "An introduction to the fundamentals of this emerging computing paradigm.", + displayPath: "test/title-match.md", + }); + + const results = store.searchFTS("quantum", 10); + expect(results.length).toBe(2); + // Title-match doc should rank higher due to BM25 column weights boosting title + expect(results[0]!.displayPath).toBe(`${collectionName}/test/title-match.md`); + + await cleanupTestDb(store); + }); + test("searchFTS respects limit parameter", async () => { const store = await createTestStore(); const collectionName = await createTestCollection();