Skip to content

feat(store): replace FTS5 default ranking with weighted BM25 scoring#245

Open
Snakeblack wants to merge 1 commit intoGentleman-Programming:mainfrom
Snakeblack:feat/fts5-bm25-weighted-ranking
Open

feat(store): replace FTS5 default ranking with weighted BM25 scoring#245
Snakeblack wants to merge 1 commit intoGentleman-Programming:mainfrom
Snakeblack:feat/fts5-bm25-weighted-ranking

Conversation

@Snakeblack
Copy link
Copy Markdown

Summary

Replace fts.rank with bm25(observations_fts, 5.0, 1.0, 0.0, 0.0, 0.0, 3.0) in the FTS5 search query to apply weighted BM25 scoring.

Weights

Column Weight Rationale
title 5.0 Highest discriminant — most semantically meaningful
content 1.0 Baseline body text
tool_name 0.0 Irrelevant for search (noise)
type 0.0 Already filtered by SearchOptions
project 0.0 Already filtered by SearchOptions
topic_key 3.0 High relational affinity

What changed

  • 2 lines in store.go: replaced fts.rank with bm25() call and updated ORDER BY to use the alias
  • 3 new tests in store_test.go: TDD cycle covering ranking order, direct topic_key route guard, and edge-case query safety

TDD Evidence

Test RED GREEN REFACTOR
TestBM25RankingOrdersTitleAboveTopicKeyAboveContent ✅ Failed (flat ranking) ✅ Passed ✅ Full suite clean
TestBM25DoesNotAffectTopicKeyDirectRoute ✅ Regression guard ✅ Passed ✅ No change needed
TestBM25SearchReturnsNoSQLErrors ✅ Regression guard ✅ Passed ✅ No change needed

Notes

  • Zero dependencies, zero schema migration
  • BM25 is native to FTS5
  • Direct topic_key route (Rank=-1000) untouched
  • TestNewErrorBranches is a pre-existing Windows file-locking failure, unrelated to this change

Closes #241

Replace fts.rank with bm25(observations_fts, 5.0, 1.0, 0.0, 0.0, 0.0, 3.0)
to apply weighted BM25 scoring in FTS5 search queries.

Weights: title=5, content=1, tool_name=0, type=0, project=0, topic_key=3.
Direct topic_key route (Rank=-1000) remains unchanged.

Closes Gentleman-Programming#241
Copilot AI review requested due to automatic review settings April 26, 2026 17:36
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the SQLite FTS5 search ranking used by Store.Search to use weighted BM25 scoring so matches in higher-signal columns (e.g., title, topic_key) rank ahead of lower-signal matches.

Changes:

  • Replace fts.rank with a weighted bm25(observations_fts, ...) AS rank score in the FTS5 search query.
  • Update ORDER BY to sort by the new rank alias.
  • Add tests covering ranking expectations, the direct topic_key route guard, and query-safety regression checks.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
internal/store/store.go Switches FTS5 ranking from fts.rank to weighted BM25 and orders by the BM25 alias.
internal/store/store_test.go Adds regression tests for BM25 ranking behavior, direct topic_key behavior, and edge-case query safety.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +6803 to +6810
if !strings.Contains(results[0].Title, "kubernetes") {
t.Fatalf("expected first result to have 'kubernetes' in title (title-match), got %q", results[0].Title)
}
if results[0].TopicKey != nil && strings.Contains(*results[0].TopicKey, "kubernetes") {
// First result should be the title-match, not the topic-match
} else if !strings.Contains(results[0].Title, "kubernetes") {
t.Fatalf("first result should be the title-match observation")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(store): replace FTS5 default ranking with weighted BM25

2 participants