-- init-db/08-embeddings.sql -- ============================================================ -- Esquema para embeddings y relaciones semánticas entre noticias -- Compatible con embeddings_worker.py (usa traduccion_embeddings) -- y mantiene una vista "embeddings" para compatibilidad previa. -- ============================================================ -- Tabla principal de embeddings por traducción (con modelo) CREATE TABLE IF NOT EXISTS traduccion_embeddings ( id SERIAL PRIMARY KEY, traduccion_id INT NOT NULL REFERENCES traducciones(id) ON DELETE CASCADE, model TEXT NOT NULL, dim INT NOT NULL, embedding DOUBLE PRECISION[] NOT NULL, created_at TIMESTAMP DEFAULT NOW(), UNIQUE (traduccion_id, model) ); -- Índices recomendados CREATE INDEX IF NOT EXISTS idx_tr_emb_traduccion_id ON traduccion_embeddings(traduccion_id); CREATE INDEX IF NOT EXISTS idx_tr_emb_model ON traduccion_embeddings(model); -- ----------------------------------------------------------------- -- Vista de compatibilidad "embeddings" -- (emula tu antigua tabla con columnas: traduccion_id, dim, vec) -- Ajusta el valor del WHERE model = '...' si usas otro modelo. -- ----------------------------------------------------------------- DO $$ BEGIN -- Si ya existe una tabla llamada embeddings, la renombramos a embeddings_legacy para evitar conflicto IF EXISTS ( SELECT 1 FROM information_schema.tables WHERE table_schema = 'public' AND table_name = 'embeddings' ) THEN EXECUTE 'ALTER TABLE embeddings RENAME TO embeddings_legacy'; END IF; EXCEPTION WHEN others THEN -- No bloqueamos la migración por esto NULL; END$$; -- Crea/actualiza la vista CREATE OR REPLACE VIEW embeddings AS SELECT te.traduccion_id, te.dim, te.embedding AS vec FROM traduccion_embeddings te WHERE te.model = 'sentence-transformers/all-MiniLM-L6-v2'; -- Nota: -- Si quieres que la vista siempre coja el embedding más reciente de CUALQUIER modelo: -- REEMPLAZA el WHERE anterior por: -- WHERE te.id IN ( -- SELECT DISTINCT ON (traduccion_id) id -- FROM traduccion_embeddings -- ORDER BY traduccion_id, created_at DESC -- ); -- ----------------------------------------------------------------- -- Relaciones semánticas entre traducciones (opcional) -- Esta tabla no la usa el worker directamente, pero permite cachear -- "noticias relacionadas" precalculadas por otro proceso/batch. -- ----------------------------------------------------------------- CREATE TABLE IF NOT EXISTS related_noticias ( traduccion_id INT NOT NULL REFERENCES traducciones(id) ON DELETE CASCADE, related_traduccion_id INT NOT NULL REFERENCES traducciones(id) ON DELETE CASCADE, score DOUBLE PRECISION NOT NULL, created_at TIMESTAMP DEFAULT NOW(), PRIMARY KEY (traduccion_id, related_traduccion_id), CHECK (traduccion_id <> related_traduccion_id) ); -- Índices para acelerar consultas en ambos sentidos CREATE INDEX IF NOT EXISTS idx_related_by_tr ON related_noticias (traduccion_id); CREATE INDEX IF NOT EXISTS idx_related_by_relatedtr ON related_noticias (related_traduccion_id); -- Sugerencias: -- - Si pretendes recalcular periódicamente, podrías limpiar por ventana temporal: -- DELETE FROM related_noticias WHERE created_at < NOW() - INTERVAL '7 days';