NestJS

Nest

Tutorial Nest: Filtrados en consultas de repositorios

Nest repositorios consultas: manejo y ejemplos. Aprende a manejar consultas en repositorios de Nest con ejemplos prácticos y detallados.

En el desarrollo de aplicaciones, especialmente aquellas que interactúan con bases de datos, es común la necesidad de filtrar o refinar los resultados obtenidos a partir de ciertos criterios. NestJS, proporciona herramientas para facilitar esta tarea cuando se trabaja con bases de datos.

En este contexto, el filtrado de datos se refiere a la práctica de definir y aplicar criterios específicos para limitar los datos recuperados de una base de datos. Esto se logra principalmente a través del uso de repositorios.

Repositorios en NestJS

Un repositorio es un patrón de diseño que separa la lógica que recupera los datos y la lógica que accede a ellos.

En NestJS, cuando se utiliza el paquete @nestjs/typeorm, se puede acceder a estos repositorios y utilizarlos para interactuar con la base de datos.

Filtrando datos con repositorios

Para filtrar datos utilizando repositorios, generalmente se usa el método find con ciertos criterios.

A continuación, se muestra un ejemplo básico:

import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm';

@Entity()
export class Usuario {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  nombre: string;

  @Column()
  edad: number;
}

Imaginemos que se quiere obtener todos los usuarios mayores de 18 años. El servicio que utiliza el repositorio podría verse así:

import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Usuario } from './usuario.entity';

@Injectable()
export class UsuarioService {
  constructor(
    @InjectRepository(Usuario)
    private readonly usuarioRepository: Repository<Usuario>,
  ) {}

  async obtenerAdultos(): Promise<Usuario[]> {
    return this.usuarioRepository.find({ 
        where: { 
            edad: MoreThan(18) 
        } 
    });
  }
}

Aquí, MoreThan es una función de TypeORM que permite crear una condición de comparación.

Otros filtros comunes de comparación disponibles son:

  • Equal: Compara si es igual.
  • MoreThan: Compara si es mayor que.
  • LessThan: Compara si es menor que.
  • In: Compara si está dentro de un arreglo de valores.

Filtrados avanzados

A medida que las aplicaciones crecen en complejidad, las necesidades de filtrado también pueden volverse más complejas. Se pueden combinar múltiples criterios, ordenar los resultados, limitar la cantidad de resultados, etc.

Combinando criterios

Para obtener usuarios mayores de 18 años y cuyo nombre comience con la letra 'A', se puede hacer lo siguiente:

async obtenerAdultosConA(): Promise<Usuario[]> {
  return this.usuarioRepository.find({
    where: {
      edad: MoreThan(18),
      nombre: Like('A%')
    }
  });
}

Aquí, se combinan múltiples condiciones en el filtro where.

Like es otra función de TypeORM que permite crear condiciones de comparación basadas en patrones.

Ordenando y limitando resultados

Para ordenar los resultados por nombre y obtener solo los primeros 10:

async obtenerTop10Adultos(): Promise<Usuario[]> {
  return this.usuarioRepository.find({
    where: { 
        edad: MoreThan(18) 
    },
    order: { 
        nombre: 'ASC' 
    },
    take: 10
  });
}
  • ASC (Ascendente): Esto ordenará los registros de menor a mayor según el campo especificado.
  • DESC (Descendente): Esto ordenará los registros de mayor a menor según el campo especificado.

Filtrado personalizado utilizando QueryBuilder

A medida que las necesidades de filtrado se vuelven más avanzadas, se puede recurrir a QueryBuilder de TypeORM. Esto ofrece una mayor flexibilidad en la construcción de consultas, permitiendo combinar, anidar y realizar operaciones más complejas.

Ejemplo de uso de QueryBuilder

Si se desea obtener usuarios mayores de 18 años pero se quiere excluir a aquellos cuyo nombre comience con la letra 'A':

import { getRepository } from 'typeorm';
import { Usuario } from './usuario.entity';

async obtenerAdultosExcluyendoA(): Promise<Usuario[]> {
  return getRepository(Usuario)
    .createQueryBuilder('usuario')
    .where('usuario.edad > :edad', { 
        edad: 18 
    })
    .andWhere('usuario.nombre NOT LIKE :nombre', { 
        nombre: 'A%' 
    })
    .getMany();
}

Con createQueryBuilder, se está creando una consulta desde cero y, con ello, se tiene un control más detallado de la misma.

Combinar entidades relacionadas

Imagine que cada usuario tiene una lista de libros asociados y se desea obtener los usuarios que tienen un libro específico:

async obtenerUsuariosConLibro(tituloLibro: string): Promise<Usuario[]> {
  return getRepository(Usuario)
    .createQueryBuilder('usuario')
    .innerJoinAndSelect('usuario.libros', 'libro', 'libro.titulo = :titulo', {
        titulo: tituloLibro 
    })
    .getMany();
}

Este ejemplo asume que existe una relación entre la entidad Usuario y una entidad Libro. Con innerJoinAndSelect, se está haciendo un JOIN entre ambas entidades basándose en un criterio específico.

Buenas prácticas

1. Reutilización de código: Si se encuentra repitiendo lógica de filtrado en diferentes partes de la aplicación, es una buena idea considerar la creación de métodos de repositorio personalizados.

2. Evitar filtrados en memoria: Siempre que sea posible, es recomendable filtrar los datos directamente en la base de datos en lugar de recuperar todos los datos y filtrarlos después en la memoria. Esto ayuda a mantener la eficiencia y reduce el uso de recursos.

3. Documentación: Debido a que las consultas pueden volverse complejas, es esencial documentar qué hace cada función y cuál es su propósito, para facilitar la comprensión por parte de otros desarrolladores y mantener la mantenibilidad del código.

Conclusión

NestJS y TypeORM ofrecen herramientas poderosas para el filtrado de datos en las aplicaciones. Desde consultas simples utilizando el método find de los repositorios hasta construcciones más avanzadas con QueryBuilder, es posible manejar una amplia gama de escenarios y necesidades.

Certifícate en Nest con CertiDevs PLUS

Ejercicios de esta lección Filtrados en consultas de repositorios

Evalúa tus conocimientos de esta lección Filtrados en consultas de repositorios con nuestros retos de programación de tipo Test, Puzzle, Código y Proyecto con VSCode, guiados por IA.

Todas las lecciones de Nest

Accede a todas las lecciones de Nest y aprende con ejemplos prácticos de código y ejercicios de programación con IDE web sin instalar nada.

Certificados de superación de Nest

Supera todos los ejercicios de programación del curso de Nest y obtén certificados de superación para mejorar tu currículum y tu empleabilidad.

En esta lección

Objetivos de aprendizaje de esta lección

  1. Comprender el concepto de filtrado de datos en desarrollo de aplicaciones.
  2. Aprender a filtrar datos utilizando repositorios en NestJS.
  3. Explorar filtrados avanzados.
  4. Conocer buenas prácticas para el filtrado de datos.