···1+-- Create GIN index on the tags array in the JSONB data field
2+-- This allows efficient querying of documents by tag
3+CREATE INDEX IF NOT EXISTS idx_documents_tags
4+ ON "public"."documents" USING gin ((data->'tags'));
5+6+-- Function to search and aggregate tags from documents
7+-- This does the aggregation in the database rather than fetching all documents
8+CREATE OR REPLACE FUNCTION search_tags(search_query text)
9+RETURNS TABLE (name text, document_count bigint) AS $$
10+BEGIN
11+ RETURN QUERY
12+ SELECT
13+ LOWER(tag::text) as name,
14+ COUNT(DISTINCT d.uri) as document_count
15+ FROM
16+ "public"."documents" d,
17+ jsonb_array_elements_text(d.data->'tags') as tag
18+ WHERE
19+ CASE
20+ WHEN search_query = '' THEN true
21+ ELSE LOWER(tag::text) LIKE '%' || search_query || '%'
22+ END
23+ GROUP BY
24+ LOWER(tag::text)
25+ ORDER BY
26+ COUNT(DISTINCT d.uri) DESC,
27+ LOWER(tag::text) ASC
28+ LIMIT 20;
29+END;
30+$$ LANGUAGE plpgsql STABLE;