2025-08-13 14:00:57 +08:00
|
|
|
|
-- ================================================
|
|
|
|
|
|
-- init.sql - Stable RAG schema with Hybrid Search
|
2025-10-30 15:15:17 +08:00
|
|
|
|
-- For pgvector ≥ 0.5, BGE-M3 (1024 dims), pg_jieba + english
|
2025-08-13 14:00:57 +08:00
|
|
|
|
-- ================================================
|
|
|
|
|
|
|
2025-08-10 09:29:40 +08:00
|
|
|
|
SET lock_timeout = '5s';
|
|
|
|
|
|
SET statement_timeout = '0';
|
|
|
|
|
|
|
2025-10-30 15:15:17 +08:00
|
|
|
|
-- 1. 必要扩展:向量 + 中文分词
|
2025-08-07 19:31:55 +08:00
|
|
|
|
CREATE EXTENSION IF NOT EXISTS vector;
|
2025-10-30 15:15:17 +08:00
|
|
|
|
CREATE EXTENSION IF NOT EXISTS pg_jieba;
|
2025-08-13 14:00:57 +08:00
|
|
|
|
|
2025-10-30 15:15:17 +08:00
|
|
|
|
-- 2. 中文 + 英文混合全文检索配置(pg_jieba + simple)
|
|
|
|
|
|
-- 自定义配置名:jieba_search
|
2025-08-13 14:00:57 +08:00
|
|
|
|
DO $$
|
|
|
|
|
|
BEGIN
|
2025-10-30 15:15:17 +08:00
|
|
|
|
IF NOT EXISTS (SELECT 1 FROM pg_ts_config WHERE cfgname = 'jieba_search') THEN
|
|
|
|
|
|
CREATE TEXT SEARCH CONFIGURATION jieba_search (PARSER = pg_jieba);
|
|
|
|
|
|
-- pg_jieba 的 token 类型包括:word, tag, symbol, number
|
|
|
|
|
|
ALTER TEXT SEARCH CONFIGURATION jieba_search
|
|
|
|
|
|
ADD MAPPING FOR word, tag, symbol, number WITH simple;
|
2025-08-13 14:00:57 +08:00
|
|
|
|
END IF;
|
|
|
|
|
|
END$$;
|
2025-08-07 19:31:55 +08:00
|
|
|
|
|
2025-10-30 15:15:17 +08:00
|
|
|
|
-- 3. 主表结构
|
2025-08-10 09:29:40 +08:00
|
|
|
|
CREATE TABLE IF NOT EXISTS public.documents (
|
|
|
|
|
|
id BIGSERIAL PRIMARY KEY,
|
|
|
|
|
|
repo TEXT NOT NULL,
|
|
|
|
|
|
path TEXT NOT NULL,
|
|
|
|
|
|
chunk_id INT NOT NULL,
|
|
|
|
|
|
content TEXT NOT NULL,
|
2025-10-30 15:15:17 +08:00
|
|
|
|
embedding VECTOR(1024),
|
2025-08-10 09:29:40 +08:00
|
|
|
|
metadata JSONB,
|
2025-08-13 14:00:57 +08:00
|
|
|
|
content_sha TEXT NOT NULL,
|
|
|
|
|
|
|
2025-10-30 15:15:17 +08:00
|
|
|
|
-- 全文检索字段(pg_jieba)
|
2025-08-13 14:00:57 +08:00
|
|
|
|
content_tsv tsvector GENERATED ALWAYS AS (
|
2025-10-30 15:15:17 +08:00
|
|
|
|
setweight(to_tsvector('jieba_search', coalesce(content, '')), 'A')
|
2025-08-13 14:00:57 +08:00
|
|
|
|
) STORED,
|
|
|
|
|
|
|
|
|
|
|
|
doc_key TEXT GENERATED ALWAYS AS (
|
|
|
|
|
|
repo || ':' || path || ':' || chunk_id
|
|
|
|
|
|
) STORED,
|
|
|
|
|
|
|
2025-08-10 09:29:40 +08:00
|
|
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
2025-08-13 14:00:57 +08:00
|
|
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
2025-08-07 19:31:55 +08:00
|
|
|
|
);
|
|
|
|
|
|
|
2025-10-30 15:15:17 +08:00
|
|
|
|
-- 4. 唯一约束
|
2025-08-13 14:00:57 +08:00
|
|
|
|
CREATE UNIQUE INDEX IF NOT EXISTS documents_doc_key_uk
|
|
|
|
|
|
ON public.documents (doc_key);
|
|
|
|
|
|
|
2025-10-30 15:15:17 +08:00
|
|
|
|
-- 5. 向量索引
|
2025-08-13 13:14:35 +08:00
|
|
|
|
CREATE INDEX IF NOT EXISTS documents_embedding_idx
|
2025-08-13 14:00:57 +08:00
|
|
|
|
ON public.documents
|
|
|
|
|
|
USING hnsw (embedding vector_cosine_ops)
|
|
|
|
|
|
WHERE embedding IS NOT NULL;
|
2025-08-10 09:29:40 +08:00
|
|
|
|
|
2025-10-30 15:15:17 +08:00
|
|
|
|
-- 6. 全文索引(pg_jieba)
|
2025-08-13 14:00:57 +08:00
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_documents_tsv
|
2025-08-10 09:29:40 +08:00
|
|
|
|
ON public.documents USING gin (content_tsv);
|
2025-08-13 14:00:57 +08:00
|
|
|
|
|
2025-10-30 15:15:17 +08:00
|
|
|
|
-- 7. 复合索引
|
2025-08-13 14:00:57 +08:00
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_documents_repo_path
|
|
|
|
|
|
ON public.documents (repo, path);
|