From e0d8359444e6ab1428947bfba97f511c5a7a3d9a Mon Sep 17 00:00:00 2001 From: Raymond Jacobson Date: Thu, 25 Jan 2024 12:44:48 -0800 Subject: [PATCH 1/2] [C-3728] Add dominant genre support to aggregate_user --- .../ddl/migrations/0049_dominant_genre.sql | 7 ++++ .../tasks/test_update_aggregates.py | 24 +++++++++++- .../src/models/users/aggregate_user.py | 4 +- .../src/tasks/update_aggregates.py | 38 ++++++++++++++++++- 4 files changed, 69 insertions(+), 4 deletions(-) create mode 100644 packages/discovery-provider/ddl/migrations/0049_dominant_genre.sql diff --git a/packages/discovery-provider/ddl/migrations/0049_dominant_genre.sql b/packages/discovery-provider/ddl/migrations/0049_dominant_genre.sql new file mode 100644 index 00000000000..8d1af6aa880 --- /dev/null +++ b/packages/discovery-provider/ddl/migrations/0049_dominant_genre.sql @@ -0,0 +1,7 @@ +begin; + alter table aggregate_user + add column if not exists dominant_genre varchar default null; + + alter table aggregate_user + add column if not exists dominant_genre_count integer not null default 0; +commit; \ No newline at end of file diff --git a/packages/discovery-provider/integration_tests/tasks/test_update_aggregates.py b/packages/discovery-provider/integration_tests/tasks/test_update_aggregates.py index 0364c401b4d..53d79638723 100644 --- a/packages/discovery-provider/integration_tests/tasks/test_update_aggregates.py +++ b/packages/discovery-provider/integration_tests/tasks/test_update_aggregates.py @@ -139,7 +139,12 @@ def test_update_aggregate_user(app): {"playlist_id": 2, "playlist_owner_id": 1, "is_album": True}, {"playlist_id": 3, "playlist_owner_id": 2}, ], - "tracks": [{"track_id": 1, "owner_id": 1}, {"track_id": 2, "owner_id": 2}], + "tracks": [ + {"track_id": 1, "owner_id": 1, "genre": "Electronic"}, + {"track_id": 2, "owner_id": 2, "genre": "Electronic"}, + {"track_id": 3, "owner_id": 2, "genre": "Pop"}, + {"track_id": 4, "owner_id": 2, "genre": "Pop"}, + ], "user": [{"user_id": 1}, {"user_id": 2}], "follows": [ {"follower_user_id": 1, "followee_user_id": 2}, @@ -172,6 +177,9 @@ def test_update_aggregate_user(app): assert aggregate_user.following_count == 1 assert aggregate_user.repost_count == 1 assert aggregate_user.track_save_count == 1 + # Dominant genre does not update by triggers + assert aggregate_user.dominant_genre is None + assert aggregate_user.dominant_genre_count == 0 aggregate_user.track_count = 0 aggregate_user.playlist_count = 0 @@ -193,3 +201,17 @@ def test_update_aggregate_user(app): assert aggregate_user.following_count == 1 assert aggregate_user.repost_count == 1 assert aggregate_user.track_save_count == 1 + assert aggregate_user.dominant_genre == "Electronic" + assert aggregate_user.dominant_genre_count == 1 + + aggregate_user2 = session.query(AggregateUser).filter_by(user_id=2).first() + assert aggregate_user2.user_id == 2 + assert aggregate_user2.track_count == 3 + assert aggregate_user2.playlist_count == 1 + assert aggregate_user2.album_count == 0 + assert aggregate_user2.follower_count == 1 + assert aggregate_user2.following_count == 1 + assert aggregate_user2.repost_count == 0 + assert aggregate_user2.track_save_count == 0 + assert aggregate_user2.dominant_genre == "Pop" + assert aggregate_user2.dominant_genre_count == 2 diff --git a/packages/discovery-provider/src/models/users/aggregate_user.py b/packages/discovery-provider/src/models/users/aggregate_user.py index 3ea88e8dda6..c9f21d16e2e 100644 --- a/packages/discovery-provider/src/models/users/aggregate_user.py +++ b/packages/discovery-provider/src/models/users/aggregate_user.py @@ -1,4 +1,4 @@ -from sqlalchemy import BigInteger, Column, Integer, text +from sqlalchemy import BigInteger, Column, Integer, String, text from src.models.base import Base from src.models.model_utils import RepresentableMixin @@ -17,3 +17,5 @@ class AggregateUser(Base, RepresentableMixin): track_save_count = Column(BigInteger, server_default=text("0")) supporter_count = Column(Integer, nullable=False, server_default=text("0")) supporting_count = Column(Integer, nullable=False, server_default=text("0")) + dominant_genre = Column(String, nullable=True) + dominant_genre_count = Column(Integer, nullable=False, server_default=text("0")) diff --git a/packages/discovery-provider/src/tasks/update_aggregates.py b/packages/discovery-provider/src/tasks/update_aggregates.py index 2efc5d88705..4fef512c4f2 100644 --- a/packages/discovery-provider/src/tasks/update_aggregates.py +++ b/packages/discovery-provider/src/tasks/update_aggregates.py @@ -201,6 +201,31 @@ group by owner_id ), +genre_counts as ( + select + owner_id as user_id, + genre, + count(*) as count + from + tracks t + where + t.is_current is true + and t.is_delete is false + and t.is_unlisted is false + and t.is_available is true + and t.stem_of is null + group by + genre, owner_id +), +ranked_genres as ( + select + user_id, + genre, + count, + rank() over (partition by user_id order by count desc) as genre_rank + from + genre_counts +), new_aggregate_user as ( select ap.user_id, @@ -210,7 +235,9 @@ coalesce(ufollower.follower_count, 0) as follower_count, coalesce(ufollowing.following_count, 0) as following_count, coalesce(ur.repost_count, 0) as repost_count, - coalesce(us.track_save_count, 0) as track_save_count + coalesce(us.track_save_count, 0) as track_save_count, + rg.genre as dominant_genre, + rg.count as dominant_genre_count from aggregate_user ap left join user_track ut on ap.user_id = ut.user_id @@ -220,6 +247,9 @@ left join user_following ufollowing on ap.user_id = ufollowing.user_id left join user_save us on ap.user_id = us.user_id left join user_repost ur on ap.user_id = ur.user_id + left join ranked_genres rg on ap.user_id = rg.user_id + where + rg.genre_rank = 1 ) update aggregate_user au @@ -230,7 +260,9 @@ follower_count = nau.follower_count, following_count = nau.following_count, repost_count = nau.repost_count, - track_save_count = nau.track_save_count + track_save_count = nau.track_save_count, + dominant_genre = nau.dominant_genre, + dominant_genre_count = nau.dominant_genre_count from new_aggregate_user nau where @@ -243,6 +275,8 @@ or au.following_count != nau.following_count or au.repost_count != nau.repost_count or au.track_save_count != nau.track_save_count + or au.dominant_genre != nau.dominant_genre + or au.dominant_genre_count != nau.dominant_genre_count ) returning au.user_id; """ From 2d1b0379ead42f4953c836585fc23bafaf6a8c87 Mon Sep 17 00:00:00 2001 From: Raymond Jacobson Date: Thu, 25 Jan 2024 15:17:13 -0800 Subject: [PATCH 2/2] Fix tests --- .../integration_tests/models/test_aggregate_counters.py | 4 ++++ packages/discovery-provider/integration_tests/utils.py | 2 ++ 2 files changed, 6 insertions(+) diff --git a/packages/discovery-provider/integration_tests/models/test_aggregate_counters.py b/packages/discovery-provider/integration_tests/models/test_aggregate_counters.py index 91280cc7812..afb6fd0d595 100644 --- a/packages/discovery-provider/integration_tests/models/test_aggregate_counters.py +++ b/packages/discovery-provider/integration_tests/models/test_aggregate_counters.py @@ -101,6 +101,8 @@ def test_aggregate_counters(app): track_save_count=0, supporter_count=0, supporting_count=0, + dominant_genre=None, + dominant_genre_count=0, ), ) @@ -117,6 +119,8 @@ def test_aggregate_counters(app): track_save_count=1, supporter_count=0, supporting_count=0, + dominant_genre=None, + dominant_genre_count=0, ), ) diff --git a/packages/discovery-provider/integration_tests/utils.py b/packages/discovery-provider/integration_tests/utils.py index 0310a465870..4b50f88b8af 100644 --- a/packages/discovery-provider/integration_tests/utils.py +++ b/packages/discovery-provider/integration_tests/utils.py @@ -454,6 +454,8 @@ def populate_mock_db(db, entities, block_offset=None): following_count=aggregate_user_meta.get("following_count", 0), repost_count=aggregate_user_meta.get("repost_count", 0), track_save_count=aggregate_user_meta.get("track_save_count", 0), + dominant_genre=aggregate_user_meta.get("dominant_genre", None), + dominant_genre_count=aggregate_user_meta.get("dominant_genre_count", 0), ) session.add(user)