Combine Rating and Review scores for performance rankings

This commit is contained in:
fullsizemalt 2025-12-26 21:32:25 -08:00
parent 992cb3db98
commit 6fdbe869cc

View file

@ -2,7 +2,7 @@ from typing import List
from fastapi import APIRouter, Depends, HTTPException, Query
from sqlmodel import Session, select, func
from database import get_session
from models import Performance, PerformanceNickname, Tag, EntityTag, Show, Venue, Rating
from models import Performance, PerformanceNickname, Tag, EntityTag, Show, Venue, Rating, Review
from schemas import PerformanceDetailRead, PerformanceNicknameCreate, PerformanceNicknameRead, PerformanceReadWithShow
from auth import get_current_user
@ -64,15 +64,38 @@ def read_performance(slug: str, session: Session = Depends(get_session)):
next_id = next_perf.id
next_slug = next_perf.slug
# Fetch ratings for all performances of this song
# Fetch ratings AND review scores for all performances of this song
# Combine both Rating and Review tables for comprehensive scores
rating_stats = session.exec(
select(Rating.performance_id, func.avg(Rating.score), func.count(Rating.id))
.where(Rating.song_id == performance.song_id)
.where(Rating.performance_id.is_not(None))
.group_by(Rating.performance_id)
).all()
rating_map = {row[0]: {"avg": row[1], "count": row[2]} for row in rating_stats}
review_stats = session.exec(
select(Review.performance_id, func.avg(Review.score), func.count(Review.id))
.where(Review.performance_id.is_not(None))
.where(Review.score.is_not(None))
.group_by(Review.performance_id)
).all()
# Merge rating and review stats
rating_map = {}
for row in rating_stats:
perf_id = row[0]
rating_map[perf_id] = {"avg": row[1] or 0.0, "count": row[2] or 0}
for row in review_stats:
perf_id = row[0]
if perf_id in rating_map:
# Combine averages weighted by count
existing = rating_map[perf_id]
total_count = existing["count"] + (row[2] or 0)
if total_count > 0:
combined_avg = ((existing["avg"] * existing["count"]) + ((row[1] or 0) * (row[2] or 0))) / total_count
rating_map[perf_id] = {"avg": combined_avg, "count": total_count}
else:
rating_map[perf_id] = {"avg": row[1] or 0.0, "count": row[2] or 0}
# Build other_performances list
other_performances = []