feat: personalized search ranking — library > similar > neither
Migration 15: add in_library and is_similar INTEGER columns to
explore_index. Backfills in_library from existing library MBIDs.
Search index FTS5 query now includes personalization in scoring:
ORDER BY bm25(...) - (ln(pop+1) * 1.5)
- (in_library * 3.0) - (is_similar * 1.5)
For equal text+popularity scores:
- Library artist beats unrelated by 3.0 points
- Similar artist beats unrelated by 1.5 points
- Library > Similar > Neither
Tier 3 (library) entries get in_library=1 via markInLibrary.
Tier 4 (similar) entries get is_similar=1 via markSimilar.
MB result reranking (boostWithIndexPopularity) adds a 10M
popularity bonus for library artists, ensuring they always
rank above non-library artists with equal text relevance.
This commit is contained in:
@@ -737,10 +737,18 @@ const (
|
||||
// is ready.
|
||||
func (e *Service) boostWithIndexPopularity(result *MBSearchResult) {
|
||||
// Look up popularity for all artist MBIDs.
|
||||
// Give a large bonus to library artists so they rank first.
|
||||
artistPop := make(map[string]int, len(result.Artists))
|
||||
|
||||
for _, a := range result.Artists {
|
||||
if pop := e.index.GetPopularity(a.MBID); pop > 0 {
|
||||
pop := e.index.GetPopularity(a.MBID)
|
||||
|
||||
// Library artists get a massive popularity bonus.
|
||||
if e.index.IsInLibrary(a.MBID) {
|
||||
pop += 10_000_000 //nolint:mnd
|
||||
}
|
||||
|
||||
if pop > 0 {
|
||||
artistPop[a.MBID] = pop
|
||||
}
|
||||
}
|
||||
@@ -751,7 +759,13 @@ func (e *Service) boostWithIndexPopularity(result *MBSearchResult) {
|
||||
rgPop := make(map[string]int, len(result.ReleaseGroups))
|
||||
|
||||
for _, rg := range result.ReleaseGroups {
|
||||
if pop := e.index.GetPopularity(rg.MBID); pop > 0 {
|
||||
pop := e.index.GetPopularity(rg.MBID)
|
||||
|
||||
if e.index.IsInLibrary(rg.MBID) {
|
||||
pop += 10_000_000 //nolint:mnd
|
||||
}
|
||||
|
||||
if pop > 0 {
|
||||
rgPop[rg.MBID] = pop
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user