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 fastapi import APIRouter, Depends, HTTPException, Query
from sqlmodel import Session, select, func from sqlmodel import Session, select, func
from database import get_session 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 schemas import PerformanceDetailRead, PerformanceNicknameCreate, PerformanceNicknameRead, PerformanceReadWithShow
from auth import get_current_user 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_id = next_perf.id
next_slug = next_perf.slug 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( rating_stats = session.exec(
select(Rating.performance_id, func.avg(Rating.score), func.count(Rating.id)) 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)) .where(Rating.performance_id.is_not(None))
.group_by(Rating.performance_id) .group_by(Rating.performance_id)
).all() ).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 # Build other_performances list
other_performances = [] other_performances = []