Files
ReadMeABook/documentation/phase3/ranking-algorithm.md
T
kikootwo f043688a71 Implement user soft-delete and improve search ranking
Adds soft-delete support for local users, including backend, API, and UI changes to allow admins to delete local users while preserving their requests. Updates user queries to exclude deleted users and allows username reuse for deleted accounts. Refines search and ranking logic for torrents: uses title-only queries for broader results, increases max results to 100, applies a minimum score threshold (30/100), and logs detailed ranking breakdowns. Updates the ranking algorithm to prioritize title/author match, adjusts scoring weights, and improves BookDate compatibility with Audiobookshelf by disabling rating-based features when unsupported. Enhances file copy operations for large files, improves metadata tagging, and updates documentation to reflect new search and ranking strategies.
2026-01-28 11:41:57 -05:00

1.5 KiB

Intelligent Ranking Algorithm

Status: Implemented

Evaluates and scores torrents to automatically select best audiobook download.

Scoring Criteria (100 points max)

1. Title/Author Match (50 pts max) - MOST IMPORTANT

  • Title matching: 0-35 pts
    • Exact substring match → 35 pts
    • No exact match → fuzzy similarity (partial credit)
  • Author presence: 0-15 pts
    • Splits authors on delimiters (comma, &, "and", " - ")
    • Filters out roles ("translator", "narrator")
    • Proportional credit for partial matches
  • Order-independent, no structure assumptions
  • Ensures correct book is selected over wrong book with better format

2. Format Quality (25 pts max)

  • M4B with chapters: 25
  • M4B without chapters: 22
  • M4A: 16
  • MP3: 10
  • Other: 3

3. Seeder Count (15 pts max)

  • Formula: Math.min(15, Math.log10(seeders + 1) * 6)
  • 1 seeder: 0pts, 10 seeders: 6pts, 100 seeders: 12pts, 1000+: 15pts

4. Size Reasonableness (10 pts max)

  • Expected: 1-2 MB/min (64-128 kbps)
  • Perfect match: 10 pts
  • Deviation → penalty
  • Unknown duration: 5 pts (neutral)

Interface

interface RankedTorrent extends TorrentResult {
  score: number;
  rank: number;
  breakdown: {
    formatScore: number;
    seederScore: number;
    sizeScore: number;
    matchScore: number;
    totalScore: number;
    notes: string[];
  };
}

function rankTorrents(
  torrents: TorrentResult[],
  audiobook: AudiobookRequest
): RankedTorrent[];

Tech Stack

  • string-similarity (fuzzy matching)
  • Regex for format detection