Cómo optimicé la búsqueda en mi SaaS con PostgreSQL Full-Text Search - Episodio 22

Optimizar-búsqueda-postgresql-full-text-search

Optimizar la búsqueda con PostgreSQL con Full-Text search era la clave para poder seguir avanzando en el proyecto.

Ya que responde a uno de los retos más importantes en mi SaaS...

Ya sabes  cómo permitir a los usuarios encontrar piezas de forma eficiente.

Esto es clave porque con miles de registros en la base de datos, usar consultas tradicionales con ILIKE o LIKE era demasiado lento y poco preciso.

Índice
  1. 🚀 Haciendo que las búsquedas sean rápidas y precisas.📅 Diario de un SaaS:
  2. 🔍 Problema: Búsquedas lentas y poco precisas
    1. 🔴 1. ILIKE y LIKE no son escalables
    2. 🔴 2. Los resultados no eran relevantes
  3. 🛠️ Implementando Full-Text Search con PostgreSQL
    1. ✅ 1. Crear un search_vector en PostgreSQL
    2. ✅ 2. Crear un índice GIN para acelerar las búsquedas
    3. ✅ 3. Modificar la API para usar Full-Text Search
  4. ❌ Errores encontrados y cómo los solucioné
    1. 🔴 ERROR: No existe el tipo de dato «tsvector» en la consulta
    2. 🔴 No se devuelven resultados en la búsqueda
  5. 💡 Aprendizajes del proceso
    1. 🔹 Full-Text Search es hasta 100 veces más rápido que ILIKE
    2. 🔹 Un buen índice GIN hace toda la diferencia
    3. 🔹 Rankear los resultados mejora la experiencia del usuario
    4. 🔹 PostgreSQL tiene herramientas avanzadas que muchos ignoran
  6. 🚀 Próximos pasos

🚀 Haciendo que las búsquedas sean rápidas y precisas.📅 Diario de un SaaS:

La solución: Full-Text Search en PostgreSQL con índices GIN. 🔥

Este sistema permite búsquedas mucho más rápidas y relevantes, optimizando la experiencia del usuario sin sacrificar rendimiento.

Por eso este este post, lo voy a dedicar a explicar cómo lo implementé, los errores que encontré y cómo los solucioné.


🔍 Problema: Búsquedas lentas y poco precisas

Antes de optimizar, el sistema de búsqueda tenía dos grandes problemas:

🔴 1. ILIKE y LIKE no son escalables

Cuando un usuario realizaba una búsqueda, PostgreSQL tenía que recorrer toda la base de datos para encontrar coincidencias.

Es decir, que generaba tiempos de respuesta altos y un consumo de recursos innecesario.

Ejemplo de una consulta típica con ILIKE:

SELECT * FROM piezas WHERE titulo ILIKE '%marca referencia%';

Esto funciona bien con pocos registros, pero cuando tienes miles o millones de filas, la base de datos se vuelve cada vez más lenta.

Y ojo, mi obsesisón pasa por tener un muy buen rendimiento en el sistema ya que esto va a garantizar una buena experiencia de usuario.

🔴 2. Los resultados no eran relevantes

Con ILIKE, una consulta devolvía cualquier coincidencia exacta, sin considerar sinónimos, errores tipográficos o términos más relevantes.

Así que un usuario que buscara "tipo de pieza" podía no encontrar una pieza cuyo título era "Tipo de pieza con sistema automático".

Necesitaba una forma de hacer las búsquedas más rápidas y precisas.

Y por eso aquí es donde entra Full-Text Search.


🛠️ Implementando Full-Text Search con PostgreSQL

✅ 1. Crear un search_vector en PostgreSQL

Lo primero fue añadir una columna search_vector, que convierte el texto en un formato optimizado para búsqueda de texto completo.

ALTER TABLE piezas ADD COLUMN search_vector tsvector;

Luego, actualizamos esta columna para que almacene los títulos y descripciones indexados:

UPDATE piezas SET search_vector = to_tsvector('spanish', titulo || ' ' || descripcion);

¿Qué hace esto?

Convierte el título y la descripción en un índice de búsqueda optimizado...

Es decir, eliminando palabras irrelevantes y permitiendo encontrar términos similares de manera eficiente.


✅ 2. Crear un índice GIN para acelerar las búsquedas

Sin un índice, PostgreSQL tendría que analizar todas las filas cada vez que se realiza una búsqueda.

En ese caso, para evitarlo, añadí un índice GIN:

CREATE INDEX idx_piezas_search ON piezas USING GIN(search_vector);

¿Por qué GIN?

Los índices GIN (Generalized Inverted Index) permiten buscar texto sin recorrer la base de datos completa, mejorando enormemente la velocidad de respuesta.


✅ 3. Modificar la API para usar Full-Text Search

En lugar de usar ILIKE, ahora la API usa to_tsquery(), lo que permite búsquedas más rápidas y relevantes:

@app.route('/buscar')
def buscar():
    query = request.args.get('q')
    sql = """
        SELECT * FROM piezas 
        WHERE search_vector @@ to_tsquery('spanish', %s)
        ORDER BY ts_rank(search_vector, to_tsquery('spanish', %s)) DESC;
    """
    cursor.execute(sql, (query, query))
    resultados = cursor.fetchall()
    return jsonify(resultados)

🔹 ¿Qué mejoras introduce esto?

  • Búsquedas más rápidas, ya que PostgreSQL usa el índice GIN en lugar de recorrer la base de datos.
  • Mayor precisión, priorizando coincidencias más relevantes.
  • Compatibilidad con sinónimos y errores tipográficos, gracias a la normalización de texto en to_tsvector().

❌ Errores encontrados y cómo los solucioné

🔴 ERROR: No existe el tipo de dato «tsvector» en la consulta

Solución:

  • Verificar que la columna search_vector existe.
  • Si se omitió, crear la columna manualmente antes de indexar los datos.

🔴 No se devuelven resultados en la búsqueda

Solución:

  • Asegurar que to_tsvector('spanish', campo) y to_tsquery('spanish', %s) usan el mismo idioma.
  • Convertir los términos de búsqueda a minúsculas para evitar problemas de coincidencia.

optimizar-postgresql-full-text-search


💡 Aprendizajes del proceso

🔹 Full-Text Search es hasta 100 veces más rápido que ILIKE

Pasamos de consultas que tardaban varios segundos a respuestas en milisegundos. 🚀

🔹 Un buen índice GIN hace toda la diferencia

Sin él, PostgreSQL haría escaneos completos de la base de datos en cada búsqueda. Con él, las respuestas son instantáneas.

🔹 Rankear los resultados mejora la experiencia del usuario

Ordenar con ts_rank() hace que las coincidencias más relevantes aparezcan primero, algo que antes no ocurría.

🔹 PostgreSQL tiene herramientas avanzadas que muchos ignoran

PostgreSQL no solo almacena datos, también ofrece optimizaciones de alto nivel para búsquedas y rendimiento.


🚀 Próximos pasos

Con las búsquedas optimizadas, el siguiente paso es cargar imágenes en AWS S3 para mejorar la gestión de medios en el SaaS. 📦🔥

➡️ ¿Has usado Full-Text Search en PostgreSQL?

¿Cómo optimizas las búsquedas en tu proyecto?

Cuéntamelo en los comentarios.

Si quieres conocer otros artículos parecidos a Cómo optimicé la búsqueda en mi SaaS con PostgreSQL Full-Text Search - Episodio 22 puedes visitar la categoría Proyecto-IA.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Subir