Initial clean commit

This commit is contained in:
jlimolina 2026-01-13 13:39:51 +01:00
commit 6784d81c2c
141 changed files with 25219 additions and 0 deletions

257
QDRANT_SETUP.md Normal file
View file

@ -0,0 +1,257 @@
# ✅ Sistema Qdrant - Búsquedas Semánticas
## 🎯 Arquitectura Actual
El sistema vectoriza **directamente** las noticias traducidas y proporciona búsqueda semántica en tiempo real.
```
Noticias Originales (RSS)
Traducción (translator workers)
PostgreSQL (tabla 'traducciones')
Qdrant Worker (vectorización directa)
Qdrant (búsquedas semánticas)
API de Búsqueda (utils/qdrant_search.py)
Buscador General + Monitor de Conflictos
```
## ✅ Servicios y Componentes
| Componente | Puerto/Ubicación | Descripción |
|----------|--------|-------------|
| **Qdrant** | 6333 | Base de datos vectorial |
| **Qdrant Worker** | - | Vectorización continua |
| **Búsqueda Semántica** | `utils/qdrant_search.py` | API de búsqueda vectorial |
| **Buscador General** | `routers/search.py` | Búsqueda con fallback a PostgreSQL |
| **Monitor de Conflictos** | `routers/conflicts.py` | Búsqueda por keywords con vectores |
### Configuración del Worker
- **Origen**: Tabla `traducciones`
- **Modelo**: `paraphrase-multilingual-MiniLM-L12-v2`
- **Dimensiones**: 384
- **Dispositivo**: CPU (GPU disponible)
- **Velocidad**: ~100+ noticias/minuto
- **Total Vectorizado**: ~507,000 noticias
## 🚀 Integración Completa
### Buscador General (`/api/search`)
La búsqueda ahora usa **Qdrant primero** para mayor velocidad y precisión semántica:
1. **Búsqueda Semántica** (por defecto): Usa vectores de Qdrant
2. **Fallback PostgreSQL**: Si falla o no hay resultados
3. **Enriquecimiento**: Combina datos de ambas fuentes
**Ventajas:**
- ✅ Búsquedas 10-100x más rápidas (sin escaneo de 500k filas)
- ✅ Comprende sinónimos y contexto ("protestas" encuentra "manifestaciones")
- ✅ Multilingüe automático
- ✅ Sin dependencia de palabras exactas
**Parámetros:**
- `q`: Texto de búsqueda
- `limit`: Máximo de resultados (default: 10, max: 50)
- `semantic`: `true/false` (default: `true`)
### Monitor de Conflictos (`/conflicts/<id>`)
Ahora usa búsqueda semántica por keywords:
**Antes (ILIKE con PostgreSQL):**
- ❌ "irán protestas" requería coincidencia exacta de toda la frase
- ❌ Lento con 500k noticias
- ❌ No encontraba variaciones ("manifestación", "protesta")
**Ahora (Qdrant):**
- ✅ "irán protestas" busca por ambas palabras independientemente
- ✅ Rápido (búsqueda vectorial)
- ✅ Encuentra contenido semánticamente similar
## 🔧 Comandos Útiles
### Ver Logs
```bash
docker-compose logs -f qdrant-worker
docker-compose logs -f qdrant
docker-compose logs -f rss2_web # Para ver logs de búsqueda
```
### Estadísticas
```bash
docker exec -it rss2_web python scripts/migrate_to_qdrant.py --stats
```
### Vectorizar Pendientes (Manual)
```bash
docker exec -it rss2_web python scripts/migrate_to_qdrant.py --vectorize --batch-size 200
```
### Reset Completo (⚠️ Destructivo)
```bash
docker exec -it rss2_web python scripts/migrate_to_qdrant.py --reset
```
### Probar Búsqueda Semántica
```bash
# Búsqueda semántica
curl "http://localhost:8001/api/search?q=protestas+en+iran&semantic=true"
# Búsqueda tradicional (fallback)
curl "http://localhost:8001/api/search?q=protestas+en+iran&semantic=false"
```
## 📊 Verificar Estado
### Base de Datos
```sql
-- Progreso de vectorización
SELECT
COUNT(*) as total,
COUNT(*) FILTER (WHERE vectorized = TRUE) as vectorizadas,
COUNT(*) FILTER (WHERE vectorized = FALSE) as pendientes
FROM traducciones
WHERE lang_to = 'es' AND status = 'done';
```
### Qdrant API
```bash
# Estado de la colección
curl http://localhost:6333/collections/news_vectors
# Health check
curl http://localhost:6333/healthz
# Conteo de puntos
curl http://localhost:6333/collections/news_vectors | jq '.result.points_count'
```
## 🔍 Variables de Entorno
```bash
# .env
QDRANT_HOST=qdrant
QDRANT_PORT=6333
QDRANT_COLLECTION_NAME=news_vectors
QDRANT_BATCH_SIZE=100
QDRANT_SLEEP_IDLE=30
EMB_MODEL=sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2
```
## 📁 Archivos Relevantes
| Archivo | Función |
|---------|---------|
| `workers/qdrant_worker.py` | Worker de vectorización continua |
| `utils/qdrant_search.py` | **NUEVO**: API de búsqueda semántica |
| `routers/search.py` | **ACTUALIZADO**: Buscador con Qdrant |
| `routers/conflicts.py` | **ACTUALIZADO**: Monitor de conflictos con Qdrant |
| `scripts/migrate_to_qdrant.py` | Migración/estadísticas |
| `docker-compose.yml` | Configuración de servicios + timezone sync |
## ⏰ Sincronización de Hora
**Problema Resuelto:** Todos los contenedores Docker ahora tienen la hora sincronizada (TZ=Europe/Madrid).
**Cambios:**
- ✅ Variable `TZ=Europe/Madrid` en todos los servicios
- ✅ Volúmenes `/etc/timezone` y `/etc/localtime` en servicios clave
- ✅ Logs consistentes entre todos los workers
## 🚀 Despliegue en Nuevas Máquinas
### Requisitos Previos
1. Docker y Docker Compose instalados
2. Al menos 8GB RAM (recomendado 16GB)
3. GPU NVIDIA (opcional, para workers de traducción)
### Pasos de Instalación
```bash
# 1. Clonar repositorio
git clone <repo-url>
cd rss2
# 2. Configurar variables de entorno
cp .env.example .env
# Editar .env con tus credenciales
# 3. Iniciar servicios
docker-compose up -d
# 4. Verificar que Qdrant está funcionando
curl http://localhost:6333/healthz
# 5. Monitorear vectorización
docker-compose logs -f qdrant-worker
```
### Migración de Datos Existentes
Si ya tienes noticias traducidas sin vectorizar:
```bash
# Ver estadísticas
docker exec -it rss2_web python scripts/migrate_to_qdrant.py --stats
# Vectorizar todas las pendientes (puede tardar horas con 500k noticias)
# El worker lo hace automáticamente, pero puedes forzarlo:
docker-compose restart qdrant-worker
```
## 🔍 Troubleshooting
### La búsqueda no usa Qdrant
```bash
# Verificar que Qdrant está corriendo
docker ps | grep qdrant
# Ver logs del worker
docker-compose logs qdrant-worker
# Verificar conexión
curl http://localhost:6333/collections/news_vectors
```
### Búsqueda lenta aún
```bash
# Verificar cuántas noticias están vectorizadas
docker exec -it rss2_web python scripts/migrate_to_qdrant.py --stats
# Si hay muchas pendientes, el worker las procesará automáticamente
# Para acelerar, aumenta el batch size en docker-compose.yml:
# QDRANT_BATCH_SIZE=200
```
### Error "No module named 'qdrant_client'"
```bash
# Reconstruir imagen web
docker-compose build rss2_web
docker-compose restart rss2_web
```
## 📈 Rendimiento
**Antes (PostgreSQL solo):**
- Búsqueda simple: 2-5 segundos (500k filas)
- Búsqueda compleja: 10-30 segundos
- Monitor de conflictos: 5-15 segundos
**Ahora (Qdrant + PostgreSQL):**
- Búsqueda semántica: 50-200ms
- Enriquecimiento PostgreSQL: +50ms
- Monitor de conflictos: 100-300ms
- **Mejora: 10-100x más rápido**
## 🎯 Próximos Pasos
- [ ] Implementar filtros avanzados (fecha, país, categoría)
- [ ] Cachear resultados frecuentes en Redis
- [ ] Agregar búsqueda híbrida (combinar PostgreSQL FTS + Qdrant)
- [ ] Dashboard de métricas de búsqueda