Commit record

Replace library search with a BM25-ranked in-memory index

Committed

2e21420464fd946f0a62c1f991781fcb88caa4ea

← All changes
Replace library search with a BM25-ranked in-memory index The search box now queries an inverted index built at startup over three fields per recording — title, blurb, and the full plain text of its editorial note (extracted from the parsed Markdown at load time, so "Search titles and notes" is finally literally true). Ranking is standard BM25 (k1=1.2, b=0.75) with per-field weights (title 3x, blurb 2x, body 1x), light plural folding and apostrophe folding instead of a stemmer, all-terms-required semantics with a graceful partial-match fallback so long queries never dead-end, and an exact-phrase bonus so today's phrase searches still win. Results order by relevance by default while a search is active — the sort control gains a "Most relevant" default option — and any explicit sort still wins. No dependencies, no JavaScript: the index is a few maps over the embedded catalog and every query is a microsecond scan. Tests cover tokenization, field weighting, phrase-bonus ordering, partial-match fallback, body-only matches (q=Pringles reaches a note body), plural folding (q=bear finds the Bears title), and punctuation-only queries; the full-title search fixture now correctly finds both parts of the two-part talk with the exact match ranked first.