-- Household co-play similarity (#1533, milestone #160 Opt 5). Minstrel is a -- single shared-library, multi-user server (no per-user library ACL), so the -- "household" is the whole instance's user set. These queries recompute -- artist–artist co-occurrence edges from play_events and store them in -- artist_similarity under the pre-provisioned source = 'user_cooccurrence' -- (whitelisted in the 0009 CHECK from day one). A periodic worker DELETEs then -- re-INSERTs so edges that fall below threshold disappear. Single-user servers -- produce no edges (the >= 2 co-player gate), so the arm is empty there. -- name: DeleteArtistCoplayEdges :exec DELETE FROM artist_similarity WHERE source = 'user_cooccurrence'; -- name: InsertArtistCoplayEdges :exec -- Two artists are "co-played" when the same users play both. score is the -- Jaccard of their distinct-player sets — coplayers / (playersA + playersB − -- coplayers) in (0,1] — which controls for globally-popular artists (an artist -- everyone plays would otherwise co-occur with everything). Only pairs with -- >= 2 distinct co-players AND Jaccard >= $1 (a floor that both prunes weak -- edges and self-limits hub artists, whose large denominators drag their -- Jaccard down) are kept. Completed plays only, 365-day window. WITH user_artists AS ( SELECT DISTINCT pe.user_id, t.artist_id FROM play_events pe JOIN tracks t ON t.id = pe.track_id WHERE pe.was_skipped = false AND pe.started_at > now() - interval '365 days' ), artist_players AS ( SELECT artist_id, count(*)::float8 AS players FROM user_artists GROUP BY artist_id ), pairs AS ( SELECT ua.artist_id AS a_id, ub.artist_id AS b_id, count(*)::float8 AS coplayers FROM user_artists ua JOIN user_artists ub ON ua.user_id = ub.user_id AND ua.artist_id <> ub.artist_id GROUP BY ua.artist_id, ub.artist_id HAVING count(*) >= 2 ), scored AS ( SELECT p.a_id, p.b_id, p.coplayers / (pa.players + pb.players - p.coplayers) AS score FROM pairs p JOIN artist_players pa ON pa.artist_id = p.a_id JOIN artist_players pb ON pb.artist_id = p.b_id ) INSERT INTO artist_similarity (artist_a_id, artist_b_id, score, source, fetched_at) SELECT a_id, b_id, score, 'user_cooccurrence', now() FROM scored WHERE score >= $1 ON CONFLICT (artist_a_id, artist_b_id, source) DO UPDATE SET score = EXCLUDED.score, fetched_at = EXCLUDED.fetched_at;