En general los cursos de NestJs son excelentes me están gustando mucho espero creen más con todo el tema de los test.
El profesor lo explica todo muy claro.
Introducción
Persistencia de Datos con MongoDB y NestJS
Programación en Python para Principiantes
Persistencia de Datos en MongoDB con Node.js
Database
Configuración de Docker Compose para MongoDB
Conexión a MongoDB usando Mongo Compass en Docker
Conexión a MongoDB con NodeJS: Instalación y Configuración Básica
Inyección de Conexiones MongoDB en NestJS
Consultas Avanzadas con MongoDB y NestJS
Conexión a MongoDB con Variables de Entorno en Node.js
Mongoose
Instalación y Configuración de Mongoose con NestJS
Creación de Esquemas de Productos con Mongoose y NestJS
Operaciones CRUD con Mongoose y Node.js
CRUD de Productos con Mongo y Nest.js
Paginación de Datos en NestJS: Implementación Práctica
Paginación y Filtros en MongoDB con Node.js
Consultas Avanzadas con Rango de Precios en MongoDB
Indexación en MongoDB: Selección y Creación de Índices Eficientes
Relaciones en MongoDB
Relaciones Embebidas en MongoDB: Documentos Anidados y Validación
Relaciones Uno a Uno en MongoDB: Referencias y Subdocumentos
Relaciones Uno a Muchos en MongoDB: Arrays Embebidos y Referenciados
Tipado de Documentos Embebidos en NestJS con Mongoose
Relaciones uno a muchos en MongoDB: Arrays y Referencias
Manipulación de Arrays en Servicios Web con Node.js
Próximos pasos
Autentificación con MongoDB y Passport en NestJS
No tienes acceso a esta clase
¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera
Los endpoints del tipo GET, además de paginar la información, pueden tener otro tipo de filtros más específicos para una regla de negocio. MongoDB permite crear cualquier tipo de filtro que necesite tu servicio.
Crear un filtro entre dos números X e Y que podrían ser años o precios de productos es un caso de uso bastante habitual en la consulta de datos.
Comienza creando el DTO para que el constructor reciba estos datos.
// products/products.dto.ts
import { ValidateIf } from 'class-validator';
export class FilterProductsDto {
@IsOptional()
@Min(0)
minPrice: number;
@ValidateIf((params) => params.minPrice)
@IsPositive()
maxPrice: number;
}
Utilizamos el decorador @ValidateIf()
para validar el precio máximo solo si existe el mínimo y también es válido.
Preparar el servicio para recibir estos nuevos datos y filtrar por rango mínimo y máximos un determinado campo del esquema.
// products/products.service.ts
import { Model, FilterQuery } from 'mongoose';
@Injectable()
export class ProductsService {
findAll(params?: FilterProductsDto) {
if (params) {
const filters: FilterQuery<Product> = {};
const { minPrice, maxPrice } = params;
if (minPrice && maxPrice) {
filters.price = { $gte: minPrice, $lte: maxPrice };
}
return this.productModel.find(filters).exec();
}
return this.productModel.find().exec();
}
}
Para crear el filtro de rangos máximos y mínimos, MongoDB utiliza operadores de comparaciones especiales:
De esta manera, el servicio está preparado para realizar un filtro numérico si el usuario ingresa el rango. Recuerda que este tipo de filtros suelen ser opcionales, el endpoint debe seguir funcionando correctamente en el caso de que no se ingrese un filtro.
Contribución creada por: Kevin Fiorentino (Platzi Contributor).
// src/products/dtos/products.dtos.ts
import {
...,
ValidateIf // 👈 new decorator
} from 'class-validator';
export class FilterProductsDto {
...
@IsOptional()
@Min(0)
minPrice: number; // 👈 new field
@ValidateIf((params) => params.minPrice)
@IsPositive()
maxPrice: number; // 👈 new field
}
// src/products/services/products.service.ts
import { Model, FilterQuery } from 'mongoose';
@Injectable()
export class ProductsService {
...
findAll(params?: FilterProductsDto) {
if (params) {
const filters: FilterQuery<Product> = {}; // 👈 create filters
const { limit, offset } = params;
const { minPrice, maxPrice } = params; // 👈
if (minPrice && maxPrice) {
filters.price = { $gte: minPrice, $lte: maxPrice };
}
return this.productModel.find(filters).skip(offset).limit(limit).exec();
}
return this.productModel.find().exec();
}
..
}
Aportes 9
Preguntas 6
En general los cursos de NestJs son excelentes me están gustando mucho espero creen más con todo el tema de los test.
El profesor lo explica todo muy claro.
Excelente clase, todo se entiende, todo funciona de lo más bien 😃
Cuando se didiregen a la ruta de docs para poder probar la documentación con swagger, me di cuenta que los parámetros están en
*required
, cuando estos deberian ser opcionales. En el FilterDto le agregué esto para que no sean obligatorios pasarlos. ¿Será la única solución?
export class FilterProductsDto {
@ApiProperty({ required: false })
@IsOptional()
@IsPositive()
limit: number;
@ApiProperty({ required: false })
@IsOptional()
@Min(0)
offset: number;
}
Se podría validad en ambos datos
@IsOptional()
@ValidateIf((params) => params.maxPrice)
@Min(0)
minPrice: number;
@ValidateIf((params) => params.minPrice)
@IsPositive()
maxPrice: number;
findAll(params?: FilterProductsDto) {
if (params) {
const filters: FilterQuery<Product> = {};
const limit = params.limit || 10;
const offset = params.offset || 0;
const { minPrice, maxPrice } = params;
if (minPrice && maxPrice) {
filters.price = { $gte: minPrice, $lte: maxPrice };
}
return this.productModel
.find(filters)
.skip(offset * limit)
.limit(limit)
.exec();
}
return this.productModel.find().exec();
}
Recuerden que no estamos validando que se pueda poner solamente maxPrice, el código nos deja, pero en nuestro product.service no tenemos nada de código para este caso, un ejemplo podría ser:
findAll(params?: FilterProductsDto) {
const filters: FilterQuery<Product> = {};
if (params) {
const { limit, offset, minPrice, maxPrice } = params;
if (minPrice && maxPrice) {
filters.price = { $gte: minPrice, $lte: maxPrice };
} else if (maxPrice && !minPrice) {
filters.price = { $lte: maxPrice };
}
return this.productModel.find(filters).skip(offset).limit(limit).exec();
}
return this.productModel.find().exec();
}
Recordar que cero es false en javascript, por lo tanto la condición debe ser:
if (minPrice >= 0 && maxPrice > 0) { }
excelente si en el query se envía un obejeto where para comparar con cualquier campo o atributo de la colección
¿Quieres ver más aportes, preguntas y respuestas de la comunidad?