Relaciones embebidas en MongoDB: Manejo y ejemplos prácticos

Clase 18 de 24Curso de NestJS: Persistencia de Datos con MongoDB

Resumen

MongoDB es una base de datos No Relacional. Aun así, requerimos la posibilidad de crear relaciones entre documentos de diferentes colecciones y es posible hacerlo.

Documento dentro de otro documento

La relación más sencilla y más utilizada es guardando un documento dentro de otro, formando una relación uno a uno embebida.

{ "name": "Producto Uno", "category": { "name": "Category", "image": "..." } }

Implementación relación uno a uno

Implementar esta lógica con Mongoose y NestJS es muy sencillo.

Paso 1: preparar el esquema

Agrega la propiedad en tu esquema que contendrá el documento embebido.

// products/product.entity.ts import { Prop, Schema, SchemaFactory, raw } from '@nestjs/mongoose'; export class Product extends Document { @Prop( raw({ name: { type: String }, image: { type: String }, }) ) category: Record<string, any>; }

El decorador @Prop() recibe un raw() con la estructura del objeto que estará dentro del objeto principal. La relación es resuelta gracias al tipado Record propio de TypeScript.

Paso 2: validar sub documento

El DTO será el encargado de validar la estructura de este sub documento.

// products/dto/category.dto.ts import { IsString, IsNotEmpty, IsUrl } from 'class-validator'; export class CreateCategoryDto { @IsString() @IsNotEmpty() readonly name: string; @IsUrl() @IsNotEmpty() readonly image: string; }

Prepara el DTO para la creación de la categoría con los campos que le corresponde a la misma que estarán embebidos dentro del documento principal.

// products/products.dto.ts import { ValidateNested } from 'class-validator'; import { CreateCategoryDto } from './category.dtos'; export class CreateProductDto { @IsNotEmpty() @ValidateNested() @ApiProperty() readonly category: CreateCategoryDto; }

Importa el DTO de la categoría y utilízalo como propiedad para el DTO de creación de productos. Agrégale el decorador @ValidateNested() para que NestJS haga la validación de la estructura correspondiente del objeto dentro.

De esta sencilla manera, puedes crear relaciones uno a una, o guardar un objeto dentro de otro en MongoDB a la vez que válidas la estructura del mismo.

Contribución creada por: Kevin Fiorentino (Platzi Contributor).


Código de ejemplo para relaciones uno a uno embebidas

// src/products/entities/product.entity.ts import { Prop, Schema, SchemaFactory, raw } from '@nestjs/mongoose'; export class Product extends Document { ... @Prop( raw({ name: { type: String }, image: { type: String }, }), ) category: Record<string, any>; // 👈 new field }
// src/products/dtos/category.dtos.ts import { IsString, IsNotEmpty, IsUrl } from 'class-validator'; export class CreateCategoryDto { ... @IsUrl() @IsNotEmpty() readonly image: string; // 👈 new field }
// src/products/dtos/products.dtos.ts import { ValidateNested, // 👈 new decorator } from 'class-validator'; import { CreateCategoryDto } from './category.dtos'; // 👈 export class CreateProductDto { @IsNotEmpty() @ValidateNested() @ApiProperty() readonly category: CreateCategoryDto; // 👈 new field }
      Relaciones embebidas en MongoDB: Manejo y ejemplos prácticos