Skip to Content

Cómo acelerar búsquedas semánticas en Odoo con Supabase cuando tu base de productos se vuelve inmanejable

Cuando tu catálogo crece, las búsquedas se vuelven lentas y frustrantes. Descubre cómo los índices vectoriales en Supabase resuelven este problema y cómo Ganemo lo ha aplicado en proyectos reales.

Cómo acelerar búsquedas semánticas en Odoo con Supabase cuando tu base de productos se vuelve inmanejable

Cuando la búsqueda deja de ser rápida

Todo funciona bien al inicio. Un catálogo con 10,000 productos parece manejable, los clientes encuentran lo que necesitan y los agentes responden en segundos. Pero cuando el catálogo se multiplica, el buscador deja de ser ágil. Las búsquedas tardan segundos en lugar de milisegundos y eso significa clientes esperando, chats que se enfrían y ventas que se diluyen.

Este problema no es técnico únicamente: es de negocio. Un buscador lento afecta la experiencia de usuario y la productividad de los equipos de atención y ventas.

La raíz del problema: búsquedas secuenciales

En PostgreSQL, al usar pgvector sin índices, cada consulta revisa fila por fila todos los embeddings. Este proceso se llama sequential scan. Con tablas pequeñas no se nota demasiado, pero al pasar de 20,000 o 50,000 productos, el tiempo de respuesta crece de forma crítica.

La solución: índices vectoriales

Un índice vectorial organiza los embeddings en grupos llamados clusters, lo que permite encontrar resultados similares de forma mucho más rápida. En pgvector, el más usado es IVFFlat, que divide la tabla en listas para reducir el número de comparaciones.

CREATE INDEX products_embeddings_embedding_ivfflat
ON public.products_embeddings
USING ivfflat (embedding vector_cosine_ops)
WITH (lists = 100);

Este comando no crea una nueva columna, sino una estructura interna que acelera la búsqueda. El número de listas suele calcularse con la raíz cuadrada del número de registros. Por ejemplo, con 50,000 filas, unas 225 listas son un buen punto de partida.

Funciones que no cambian

Tu lógica de búsqueda no necesita modificarse al crear el índice. Por ejemplo, si usas esta función para buscar productos similares:

CREATE OR REPLACE FUNCTION public.search_vectors(
    query_embedding vector(1536),
    top_n int DEFAULT 3
)
RETURNS TABLE (
    id_odoo integer,
    name text,
    maquina text,
    semantic_text text,
    similarity float
) AS $$
BEGIN
    RETURN QUERY
    SELECT
        p.id_odoo,
        p.name,
        p.maquina,
        p.semantic_text,
        1 - (p.embedding <=> query_embedding) AS similarity
    FROM public.products_embeddings p
    ORDER BY p.embedding <=> query_embedding
    LIMIT top_n;
END;
$$ LANGUAGE plpgsql STABLE;

La función sigue funcionando igual. PostgreSQL decidirá si usar el índice o un escaneo secuencial. El cambio es invisible para el usuario final: lo único que notará es velocidad.

Historias reales con Ganemo

Un distribuidor de repuestos que volvió a confiar en su buscador

Un distribuidor con más de 13,000 productos usaba Odoo para atender a clientes por WhatsApp. Cuando su catálogo creció a 50,000, las respuestas demoraban casi dos segundos. Ganemo implementó un índice IVFFlat con 225 listas. El resultado: búsquedas en menos de 100 ms y agentes satisfechos con el sistema.

La empresa de maquinaria que necesitaba precisión

Una empresa de alquiler de maquinaria amarilla recibía consultas como “¿Qué filtro sirve para el modelo Caterpillar 320D?”. Antes, la respuesta dependía de la memoria de los vendedores. Ganemo aplicó embeddings con índices vectoriales para devolver la lista de repuestos compatibles en segundos. El resultado fue un aumento del 30% en ventas cruzadas.

Un centro de soporte que redujo tiempos de atención

Una compañía de servicios recibía más de 200 tickets diarios con preguntas repetitivas. Ganemo construyó un buscador semántico sobre sus manuales técnicos. Los agentes comenzaron a recibir respuestas sugeridas en tiempo real. El tiempo promedio de resolución se redujo en un 45%.

Mantenimiento y buenas prácticas

  • Los índices se actualizan automáticamente con nuevos registros.
  • Puedes recrearlos si cambias el número de listas:
DROP INDEX IF EXISTS products_embeddings_embedding_ivfflat;
CREATE INDEX products_embeddings_embedding_ivfflat
ON public.products_embeddings
USING ivfflat (embedding vector_cosine_ops)
WITH (lists = 200);
  • Si notas lentitud después de muchos cambios, refresca con REINDEX.

Checklist rápido

  1. Si tu tabla tiene menos de 20,000 registros, no es urgente usar índice.
  2. Si superas esa cifra, crea un índice IVFFlat con √n listas.
  3. No cambies tus funciones: el índice se aplica automáticamente.
  4. Verifica con EXPLAIN ANALYZE que el índice esté en uso.

Conclusión

La búsqueda semántica deja de ser un lujo para convertirse en una necesidad cuando los catálogos crecen. Los índices vectoriales en Supabase permiten mantener la experiencia ágil, incluso con cientos de miles de registros. En Ganemo lo hemos comprobado: con la estrategia correcta, los segundos se convierten en milisegundos, y la diferencia se siente tanto en la atención al cliente como en las métricas de negocio.

Cómo acelerar búsquedas semánticas en Odoo con Supabase cuando tu base de productos se vuelve inmanejable
Wilfredo Fernando Pastor Avila September 26, 2025
Share this post
Archive
Sign in to leave a comment
Picking y Packing: El Caos en Tu Almacén que Está Costando Dinero (Y Cómo Solucionarlo)
Aprende a diferenciar entreDescubre cómo optimizar los procesos de recolección y empaquetado en tu almacén para aumentar la eficiencia y reducir errores costosos