From 8bab324649bd926a496e0b771b5eef9e5d28488d Mon Sep 17 00:00:00 2001 From: thorwebdev Date: Thu, 6 Apr 2023 12:44:14 +0800 Subject: [PATCH] feat: add next.js openai doc search starter template. --- .../SQLEditor/SQLEditor.constants.ts | 88 ++++++++++++++++++- studio/lib/vercelConfigs.ts | 22 +++++ 2 files changed, 109 insertions(+), 1 deletion(-) diff --git a/studio/components/interfaces/SQLEditor/SQLEditor.constants.ts b/studio/components/interfaces/SQLEditor/SQLEditor.constants.ts index f1b8e5c4c85..49dec8330ed 100644 --- a/studio/components/interfaces/SQLEditor/SQLEditor.constants.ts +++ b/studio/components/interfaces/SQLEditor/SQLEditor.constants.ts @@ -1070,5 +1070,91 @@ select 'table hit rate' as name, sum(heap_blks_hit) / nullif(sum(heap_blks_hit) + sum(heap_blks_read),0) as ratio from pg_statio_user_tables;`, - } + }, + { + id: 20, + type: 'quickstart', + title: 'OpenAI Vector Search', + description: 'Template for the Next.js OpenAI Doc Search Starter.', + sql: ` +-- Enable pg_vector extension +create extension if not exists vector with schema public; + +-- Create tables +create table "public"."nods_page" ( + id bigserial primary key, + parent_page_id bigint references public.nods_page, + path text not null unique, + checksum text, + meta jsonb, + type text, + source text +); +alter table "public"."nods_page" enable row level security; + +create table "public"."nods_page_section" ( + id bigserial primary key, + page_id bigint not null references public.nods_page on delete cascade, + content text, + token_count int, + embedding vector(1536), + slug text, + heading text +); +alter table "public"."nods_page_section" enable row level security; + +-- Create embedding similarity search functions +create or replace function match_page_sections(embedding vector(1536), match_threshold float, match_count int, min_content_length int) +returns table (id bigint, page_id bigint, slug text, heading text, content text, similarity float) +language plpgsql +as $$ +#variable_conflict use_variable +begin + return query + select + nods_page_section.id, + nods_page_section.page_id, + nods_page_section.slug, + nods_page_section.heading, + nods_page_section.content, + (nods_page_section.embedding <#> embedding) * -1 as similarity + from nods_page_section + + -- We only care about sections that have a useful amount of content + where length(nods_page_section.content) >= min_content_length + + -- The dot product is negative because of a Postgres limitation, so we negate it + and (nods_page_section.embedding <#> embedding) * -1 > match_threshold + + -- OpenAI embeddings are normalized to length 1, so + -- cosine similarity and dot product will produce the same results. + -- Using dot product which can be computed slightly faster. + -- + -- For the different syntaxes, see https://github.com/pgvector/pgvector + order by nods_page_section.embedding <#> embedding + + limit match_count; +end; +$$; + +create or replace function get_page_parents(page_id bigint) +returns table (id bigint, parent_page_id bigint, path text, meta jsonb) +language sql +as $$ + with recursive chain as ( + select * + from nods_page + where id = page_id + + union all + + select child.* + from nods_page as child + join chain on chain.parent_page_id = child.id + ) + select id, parent_page_id, path, meta + from chain; +$$; +`.trim(), + }, ] diff --git a/studio/lib/vercelConfigs.ts b/studio/lib/vercelConfigs.ts index 5217cfc99f4..c59555650ed 100644 --- a/studio/lib/vercelConfigs.ts +++ b/studio/lib/vercelConfigs.ts @@ -64,6 +64,28 @@ export const VERCEL_INTEGRATION_CONFIGS = [ }, ], }, + { + id: 'nextjs-open-ai-doc-search', + name: 'Next.js OpenAI Doc Search Starter', + template: QuickStart.find((x) => x.title == 'OpenAI Vector Search'), + envs: [ + { + key: 'NEXT_PUBLIC_SUPABASE_URL', + alias: INTEGRATION_ENVS_ALIAS.ENDPOINT, + type: 'encrypted', + }, + { + key: 'NEXT_PUBLIC_SUPABASE_ANON_KEY', + alias: INTEGRATION_ENVS_ALIAS.ANONKEY, + type: 'encrypted', + }, + { + key: 'SUPABASE_SERVICE_ROLE_KEY', + alias: INTEGRATION_ENVS_ALIAS.SERVICEKEY, + type: 'encrypted', + }, + ], + }, { id: 'supabase-todo-list', name: 'Todo List Database',