如何在关联表中基于当前用户过滤Supabase查询?
可行解决方案
方案1:优化Supabase关联查询(避免重复+精准过滤)
你的方案一出现重复条目,是因为左连接时拉取了所有用户的user_shows记录,而非仅当前用户的。调整思路:先限定user_shows只关联当前用户,再过滤未观看内容,同时用distinct确保结果无重复。
代码示例:
let query = supabase.from('shows').select('*, user__shows!left (*)'); if ($user) { // 先锁定当前用户的关联记录,再排除已观看项 query = query .eq('user__shows.user_id', $user.id) .not('user__shows.watched', 'is', true) .distinct(); // 去重保证单节目只返回一条结果 }
更高效的子查询写法(直接排除用户已观看的节目ID):
if ($user) { // 先获取当前用户已观看的节目ID列表 const watchedShows = await supabase .from('user_shows') .select('show') .eq('user_id', $user.id) .eq('watched', true); // 排除这些ID对应的节目 query = query.not('id', 'in', watchedShows.data.map(item => item.show)); }
方案2:优化SQL视图支持用户过滤
你的视图问题在于未预留用户过滤入口,调整视图保留全量数据,查询时追加用户条件即可:
第一步:调整视图(移除不必要的GROUP BY,右连接本身不会产生重复,除非单节目对应用户多条记录)
create view browse as SELECT shows.id, title, year, blurb, imdb_rating, imdb_count, seasons, trailer, status, runtime, country, language, episodes, genres, network, user_shows.user_id, user_shows.watched, user_shows.hidden FROM shows LEFT JOIN user_shows ON user_shows.show = shows.id;
第二步:查询视图时过滤当前用户
let query = supabase.from('browse'); if ($user) { // 筛选当前用户的关联记录,或无用户关联的节目(未被任何用户标记的) query = query.or(`user_id.eq.${$user.id},user_id.is.null`).not('watched', 'is', true); }
方案3:利用Supabase行级安全(RLS)简化逻辑
如果你的user_shows表开启了RLS,添加规则仅允许当前用户查看自己的记录:
CREATE POLICY "用户仅能查看自己的user_shows记录" ON user_shows FOR SELECT USING (auth.uid() = user_id);
之后直接用你最初的左连接查询即可,RLS会自动过滤其他用户的user_shows记录,不会出现重复,且逻辑更安全:
let query = supabase.from('shows').select('*, user__shows!left (*)'); if ($user) { query = query.not('user__shows.watched', 'is', true); }
内容的提问来源于stack exchange,提问作者user19896971
相关产品推荐
相关产品推荐

