Relaciones Uno a Muchos Referenciadas en MongoDB
Clase 22 de 24 • Curso de NestJS: Persistencia de Datos con MongoDB
Contenido del curso
- 4

Configuración y ejecución de MongoDB con Docker Compose
08:51 - 5

Conexión a Base de Datos MongoDB con Mongo Compass
05:05 - 6

Instalación y conexión de MongoDB en Node con driver oficial
06:59 - 7

Inyección de Conexiones MongoDB en Servicios NestJS
06:57 - 8

Consultas a MongoDB con Nest.js: Implementación de Endpoints
04:46 - 9

Variables de Entorno para Configuración de MongoDB en Node.js
10:43
- 10

Instalación y Configuración de Mongoose con NestJS
07:52 - 11

Definición de Esquemas en Mongoose para eCommerce con NestJS
07:45 - 12

Operaciones CRUD con MongoDB y Node.js en un Servicio de Productos
09:29 - 13

Creación, actualización y eliminación de productos en MongoDB
10:12 - 14

Validación de MongoID con Pipes en NestJS
06:38 - 15

Paginación en MongoDB con DTOs y Validaciones en NestJS
11:13 - 16

Consultas Avanzadas con Rangos de Precios en MongoDB
07:30 - 17

Indexación en MongoDB: Cómo optimizar consultas rápidas
03:11
- 18

Relaciones embebidas en MongoDB: Manejo y ejemplos prácticos
07:55 - 19

Relaciones uno a uno referenciadas en MongoDB
12:20 - 20

Relaciones Uno a Muchos en MongoDB: Arrays Embebidos vs Referenciados
09:28 - 21
Tipado de Documentos Embebidos en NestJS con Mongoose
01:49 - 22

Relaciones Uno a Muchos Referenciadas en MongoDB
14:36 - 23

Manipulación de Arrays en E-commerce: Métodos y Endpoints
13:08
Es crucial diseñar bien tu base de datos. Las relaciones uno a muchos pueden crecer indefinidamente y es importante considerar la escalabilidad de tu base de datos.
Relaciones uno a muchos embebidas vs. referenciadas
A lo igual que las relaciones uno a uno, las relaciones uno a muchos requieren contemplar la posible actualización de todo ese array de documentos. Tener un array de objetos puede no ser escalable y una no muy buena decisión de arquitectura de la base de datos.
Estos problemas se solucionan creando arrays de referencias. Un simple array de string que contendrá un item por cada ID al cual deseas hacer referencia dentro de un objeto principal.
Relaciones referenciadas
Veamos como puedes crear este tipo de relación donde un documento contendrá un array de IDs que hacen referencia a otros documentos de la base de datos.
Paso 1: preparación del esquema
Prepara la propiedad correspondiente en tu esquema que contendrá el array de referencias.
// users/order.entity.ts
import { Document, Types } from 'mongoose';
import { Product } from '../../products/entities/product.entity';
@Schema()
export class Order extends Document {
@Prop({ type: [{ type: Types.ObjectId, ref: Product.name }] })
products: Types.Array<Product>;
}
Observa que el decorador @Prop() recibe como tipo un Types.ObjectId que a su vez se encuentra encerrado por un array []. También, tienes que tipar la propiedad con Types.Array<> proveniente desde mongoose.
De esta simple manera, Mongoose sabe que la propiedad products contiene un array de MongoID.
Paso 2: preparar el DTO para la validación de datos
El DTO solo necesita recibir un array de string[] que es el equivalente para un array de MongoID.
// users/order.dto.ts
import { IsMongoId, IsNotEmpty, IsDate, IsArray } from 'class-validator';
import { OmitType, PartialType } from '@nestjs/swagger';
export class CreateOrderDto {
@IsArray()
@IsNotEmpty()
readonly products: string[];
}
Utiliza el decorador @IsArray() para validar que efectivamente se trate de un array.
Paso 3: GET de documentos referenciados
Realizar un “Join” o, como se lo conoce en MongoDB, un “Populate” es muy sencillo. Basta con agregar la configuración después del método de búsqueda indicando el nombre de la propiedad a popular.
// users/orders.service.ts
export class OrdersService {
constructor(@InjectModel(Order.name) private orderModel: Model<Order>) {}
findAll() {
return this.orderModel
.find()
.populate('products')
.exec();
}
}
Mongoose sabrá a qué colección ir a buscar los documentos al estar referenciado y tipado desde el esquema.
De esta manera, tu base de datos está lista para manipular grandes volúmenes de datos con los mejores tipos de relaciones que existen. Utiliza el tipo de relación más apropiado para cada escenario.
Contribución creada por: Kevin Fiorentino (Platzi Contributor).
Código de ejemplo de relaciones uno a muchos referenciadas
// src/users/entities/order.entity.ts
import { Document, Types } from 'mongoose';
import { Customer } from './customer.entity';
import { Product } from '../../products/entities/product.entity';
@Schema()
export class Order extends Document {
...
@Prop({ type: Types.ObjectId, ref: Customer.name, required: true })
customer: Customer | Types.ObjectId; // 👈 relation 1:1 customer
@Prop({ type: [{ type: Types.ObjectId, ref: Product.name }] })
products: Types.Array<Product>; // 👈 relation 1:N
}
// src/users/dtos/order.dto.ts
import { IsMongoId, IsNotEmpty, IsDate, IsArray } from 'class-validator';
import { OmitType, PartialType } from '@nestjs/swagger'; // 👈 use OmitType
export class CreateOrderDto {
@IsNotEmpty()
@IsMongoId()
readonly customer: string;
@IsDate()
@IsNotEmpty()
readonly date: Date;
@IsArray()
@IsNotEmpty()
readonly products: string[];
}
export class UpdateOrderDto extends PartialType(
OmitType(CreateOrderDto, ['products']), // 👈 implement OmitType
) {}
// src/users/services/orders.service.ts
export class OrdersService {
constructor(@InjectModel(Order.name) private orderModel: Model<Order>) {}
findAll() {
return this.orderModel
.find()
.populate('customer') // 👈 join customer 1:1
.populate('products') // 👈 join products 1:N
.exec();
}
}