From 9a304d92fba2e79c8a4166522a74b9ff920e67a3 Mon Sep 17 00:00:00 2001 From: Quan Cao Date: Tue, 23 Sep 2025 11:05:44 +0700 Subject: [PATCH 1/3] Fetch necessary labels data in snippets --- .../sql/get_snippet_labels_function.sql | 25 +++------ .../database/sql/get_snippets_function.sql | 53 +++++++++++++------ 2 files changed, 44 insertions(+), 34 deletions(-) diff --git a/supabase/database/sql/get_snippet_labels_function.sql b/supabase/database/sql/get_snippet_labels_function.sql index 761e769..a6bde13 100644 --- a/supabase/database/sql/get_snippet_labels_function.sql +++ b/supabase/database/sql/get_snippet_labels_function.sql @@ -18,28 +18,19 @@ BEGIN WHEN p_language = 'spanish' THEN l.text_spanish ELSE l.text END, - 'created_by', l.created_by, - 'is_ai_suggested', l.is_ai_suggested, - 'applied_by', sl.applied_by, - 'applied_at', sl.created_at, - 'upvoted_by', COALESCE(upvote_users, '[]'::jsonb) + 'upvote_count', COALESCE(upvote_counts.count, 0), + 'upvoted_by_me', COALESCE(upvote_counts.upvoted_by_current_user, false) )), '[]'::jsonb) ) INTO result FROM public.snippet_labels sl JOIN public.labels l ON sl.label = l.id - LEFT JOIN ( - SELECT lu.snippet_label, jsonb_agg(jsonb_build_object( - 'id', u.id, - 'email', u.email, - 'upvoted_at', lu.created_at - )) AS upvote_users + LEFT JOIN LATERAL ( + SELECT + COUNT(*) AS count, + BOOL_OR(lu.upvoted_by = current_user_id) AS upvoted_by_current_user FROM public.label_upvotes lu - JOIN auth.users u ON lu.upvoted_by = u.id -- Join to get user email - WHERE lu.snippet_label IN ( - SELECT id FROM public.snippet_labels WHERE snippet = snippet_id - ) -- Filter to only include upvotes for the specific snippet - GROUP BY lu.snippet_label - ) lu ON sl.id = lu.snippet_label + WHERE lu.snippet_label = sl.id + ) upvote_counts ON TRUE WHERE sl.snippet = snippet_id; RETURN COALESCE(result, jsonb_build_object('snippet_id', snippet_id, 'labels', '[]'::jsonb)); diff --git a/supabase/database/sql/get_snippets_function.sql b/supabase/database/sql/get_snippets_function.sql index 50450e2..2bd346f 100644 --- a/supabase/database/sql/get_snippets_function.sql +++ b/supabase/database/sql/get_snippets_function.sql @@ -29,7 +29,33 @@ BEGIN user_is_admin := COALESCE('admin' = ANY(user_roles), FALSE); - CREATE TEMP TABLE filtered_snippets AS + CREATE TEMP TABLE filtered_snippets AS ( + -- Pre-compute all label data with upvote counts + WITH label_data AS ( + SELECT + sl.snippet, + COALESCE(jsonb_agg( + jsonb_build_object( + 'id', l.id, + 'text', CASE + WHEN p_language = 'spanish' THEN l.text_spanish + ELSE l.text + END, + 'upvote_count', COALESCE(upvote_counts.count, 0), + 'upvoted_by_me', COALESCE(upvote_counts.upvoted_by_current_user, false) + ) + ), '[]'::jsonb) AS labels + FROM public.snippet_labels sl + JOIN public.labels l ON sl.label = l.id + LEFT JOIN LATERAL ( + SELECT + COUNT(*) AS count, + BOOL_OR(lu.upvoted_by = current_user_id) AS upvoted_by_current_user + FROM public.label_upvotes lu + WHERE lu.snippet_label = sl.id + ) upvote_counts ON TRUE + GROUP BY sl.snippet + ) SELECT s.id, s.recorded_at, @@ -55,7 +81,7 @@ BEGIN s.confidence_scores, s.language, s.context, - (get_snippet_labels(s.id, p_language) -> 'labels') AS labels, + COALESCE(ld.labels, '[]'::jsonb) AS labels, jsonb_build_object( 'id', a.id, 'radio_station_name', a.radio_station_name, @@ -63,16 +89,14 @@ BEGIN 'location_state', a.location_state, 'location_city', a.location_city ) AS audio_file, - CASE - WHEN us.id IS NOT NULL THEN true - ELSE false - END AS starred_by_user, + us.id IS NOT NULL AS starred_by_user, ul.value AS user_like_status, + uhs.snippet IS NOT NULL AS hidden, like_counts.likes AS like_count, - like_counts.dislikes AS dislike_count, - uhs.snippet IS NOT NULL AS hidden + like_counts.dislikes AS dislike_count FROM snippets s LEFT JOIN audio_files a ON s.audio_file = a.id + LEFT JOIN label_data ld ON ld.snippet = s.id LEFT JOIN user_star_snippets us ON us.snippet = s.id AND us."user" = current_user_id LEFT JOIN user_like_snippets ul ON ul.snippet = s.id AND ul."user" = current_user_id LEFT JOIN user_hide_snippets uhs ON uhs.snippet = s.id @@ -88,11 +112,7 @@ BEGIN -- If user is admin, show all snippets (including hidden ones) -- If user is not admin, only show non-hidden snippets user_is_admin OR - NOT EXISTS ( - SELECT 1 - FROM user_hide_snippets uhs - WHERE uhs.snippet = s.id - ) + uhs.snippet IS NULL ) AND ( p_filter IS NULL OR @@ -273,14 +293,13 @@ BEGIN WHEN p_order_by = 'upvotes' THEN s.upvote_count + s.like_count WHEN p_order_by = 'comments' THEN s.comment_count WHEN p_order_by = 'activities' THEN - CASE + CASE WHEN s.user_last_activity IS NULL THEN 0 ELSE EXTRACT(EPOCH FROM s.user_last_activity) END - WHEN p_order_by IS NULL OR p_order_by = 'latest' OR p_order_by = '' THEN EXTRACT(EPOCH FROM s.recorded_at) - ELSE EXTRACT(EPOCH FROM s.recorded_at) END DESC, - s.recorded_at DESC; + s.recorded_at DESC -- Default for all other cases, including p_order_by = 'latest' + ); SELECT COUNT(*) INTO total_count FROM filtered_snippets; From e9a4122682fbaa1784b7fee62917d1262fdb315f Mon Sep 17 00:00:00 2001 From: Quan Cao Date: Tue, 23 Sep 2025 11:06:32 +0700 Subject: [PATCH 2/3] Create indexes for efficient snippet fetching --- supabase/database/sql/optimize_label_indexes.sql | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 supabase/database/sql/optimize_label_indexes.sql diff --git a/supabase/database/sql/optimize_label_indexes.sql b/supabase/database/sql/optimize_label_indexes.sql new file mode 100644 index 0000000..8f5f108 --- /dev/null +++ b/supabase/database/sql/optimize_label_indexes.sql @@ -0,0 +1,10 @@ +-- Indexes to optimize the CTE-based label aggregation query + +-- 1. Additional index for label_upvotes to optimize the LATERAL join +CREATE INDEX IF NOT EXISTS idx_label_upvotes_snippet_label_upvoted_by +ON public.label_upvotes USING btree (snippet_label, upvoted_by); + +-- 2. Index for main snippets filtering +CREATE INDEX IF NOT EXISTS idx_snippets_status_confidence +ON public.snippets USING btree (status, (((confidence_scores->>'overall'))::INTEGER)) +WHERE (status = 'Processed'::processing_status); From 27b403ac5c7b7f102f5a987c1e6f2469c68219da Mon Sep 17 00:00:00 2001 From: Quan Cao Date: Tue, 23 Sep 2025 11:07:36 +0700 Subject: [PATCH 3/3] Remove unused file --- .../sql/search_related_public_snippets.sql | 84 ------------------- 1 file changed, 84 deletions(-) delete mode 100644 supabase/database/sql/search_related_public_snippets.sql diff --git a/supabase/database/sql/search_related_public_snippets.sql b/supabase/database/sql/search_related_public_snippets.sql deleted file mode 100644 index 3b65b55..0000000 --- a/supabase/database/sql/search_related_public_snippets.sql +++ /dev/null @@ -1,84 +0,0 @@ -CREATE OR REPLACE FUNCTION search_related_snippets_public( - snippet_id uuid, - p_language TEXT DEFAULT 'english', - match_threshold float DEFAULT 0.7, - match_count int DEFAULT 5 -) -RETURNS jsonb -SECURITY DEFINER AS $$ -DECLARE - source_embedding vector(3072); - result jsonb; -BEGIN - -- Get the source snippet's embedding - SELECT embedding INTO source_embedding - FROM snippet_embeddings - WHERE snippet = snippet_id; - - -- If no embedding found, return empty array - IF source_embedding IS NULL THEN - RETURN '[]'::jsonb; - END IF; - - WITH similar_snippets AS ( - SELECT - s.id, - s.title, - s.file_path, - s.recorded_at, - s.comment_count, - s.start_time, - a.radio_station_name, - a.radio_station_code, - a.location_state, - CASE - WHEN p_language = 'spanish' THEN s.summary ->> 'spanish' - ELSE s.summary ->> 'english' - END AS summary, - 1 - (se.embedding <=> source_embedding) as similarity, - jsonb_agg(l) as labels - FROM snippet_embeddings se - JOIN snippets s ON s.id = se.snippet - JOIN audio_files a ON a.id = s.audio_file - LEFT JOIN snippet_labels sl ON s.id = sl.snippet - LEFT JOIN labels l ON sl.label = l.id - WHERE - se.snippet != snippet_id - AND 1 - (se.embedding <=> source_embedding) > match_threshold - AND se.status = 'Processed' - GROUP BY - s.id, - s.title, - s.file_path, - s.recorded_at, - s.comment_count, - s.start_time, - a.radio_station_name, - a.radio_station_code, - a.location_state, - summary, - similarity - ORDER BY similarity DESC - LIMIT match_count - ) - SELECT jsonb_agg( - jsonb_build_object( - 'id', ss.id, - 'title', ss.title, - 'radio_station_name', ss.radio_station_name, - 'radio_station_code', ss.radio_station_code, - 'location_state', ss.location_state, - 'summary', ss.summary, - 'labels', ss.labels, - 'recorded_at', ss.recorded_at, - 'comment_count', ss.comment_count, - 'similarity', ss.similarity, - 'file_path', ss.file_path, - 'start_time', ss.start_time - ) - ) INTO result - FROM similar_snippets ss; - - RETURN COALESCE(result, '[]'::jsonb); -END; -$$ LANGUAGE plpgsql;