馃摑 Modelado de datos: documentos y colecciones
MongoDB no usa tablas ni filas como los sistemas SQL, sino documentos JSON dentro de colecciones. Aqu铆 aprender谩s c贸mo decidir **qu茅 datos van juntos en un mismo documento** y **cu谩ndo separarlos en distintas colecciones**.
馃摎 Conceptos clave
- Un documento es una estructura JSON (BSON internamente) — contiene pares clave:valor.
- Una colecci贸n agrupa documentos del mismo tipo o prop贸sito.
- No hay esquema r铆gido, pero puedes definir
JSON Schemapara validar estructura. - El dise帽o influye directamente en el rendimiento de lectura/escritura.
馃憠 En MongoDB, **dise帽as seg煤n c贸mo consultas los datos, no seg煤n las relaciones.**
1️⃣ Principios b谩sicos del modelado
- Modela seg煤n consultas frecuentes: qu茅 datos necesitas juntos.
- Piensa en documentos, no en tablas.
- Embebe (embed) datos que se usan siempre junto al padre.
- Referencia (reference) datos independientes o muy grandes.
Regla r谩pida: “Si los datos se consultan juntos, gu谩rdalos juntos.”
2️⃣ Ejemplo: tienda online — productos, pedidos y usuarios
En SQL tendr铆as tablas con claves for谩neas; en MongoDB puedes hacerlo as铆:
// Producto
{
_id: ObjectId("..."),
name: "Auriculares Bluetooth",
sku: "AUR-01",
price: 49.90,
categories: ["audio", "tecnolog铆a"],
stock: 120
}
// Usuario
{
_id: ObjectId("..."),
name: "Laura Garc铆a",
email: "laura@gmail.com",
passwordHash: "...",
address: {
calle: "Gran V铆a 10",
ciudad: "Madrid",
cp: "28013"
}
}
// Pedido con items embebidos
{
_id: ObjectId("..."),
userId: ObjectId("..."),
createdAt: ISODate("2025-11-13T10:00:00Z"),
total: 99.80,
items: [
{ productId: ObjectId("..."), name: "Auriculares Bluetooth", qty: 2, price: 49.90 }
],
status: "pending"
}
Aqu铆 el pedido referencia al usuario (userId), pero embeber el detalle de cada producto dentro del pedido evita tener que hacer varias consultas cuando lo visualizas.
3️⃣ Cu谩ndo embeber documentos
- El subdocumento pertenece exclusivamente al padre.
- Se consulta y modifica junto con el documento principal.
- El tama帽o total del documento no supera los 16 MB (l铆mite de BSON).
// Ejemplo: comentarios embebidos en un post
{
_id: ObjectId("..."),
titulo: "Novedades MongoDB 7.0",
contenido: "Detalles y nuevas funciones...",
comentarios: [
{ autor: "Ana", texto: "Excelente post!", fecha: new Date() },
{ autor: "Carlos", texto: "Muy 煤til, gracias!", fecha: new Date() }
]
}
✅ Ventaja: consultas m谩s r谩pidas — todo est谩 en un 煤nico documento.
⚠️ Desventaja: si hay demasiados subdocumentos, el documento puede crecer mucho.
4️⃣ Cu谩ndo referenciar
- El subdocumento se comparte entre varios documentos (ej. un producto aparece en muchos pedidos).
- Se actualiza por separado o con frecuencia.
- Su tama帽o es grande o crece indefinidamente.
// Ejemplo: relaci贸n usuario → pedidos
{
_id: ObjectId("..."),
name: "Laura",
email: "laura@gmail.com"
}
{
_id: ObjectId("..."),
userId: ObjectId("..."), // referencia
items: [ ... ],
total: 99.80
}
Luego puedes combinar ambas colecciones con $lookup (join equivalente) si necesitas unir datos.
// Unir pedidos con datos de usuario
db.orders.aggregate([
{
$lookup: {
from: "usuarios",
localField: "userId",
foreignField: "_id",
as: "usuario"
}
},
{ $unwind: "$usuario" }
])
5️⃣ Patr贸n mixto (embed + reference)
Es com煤n mezclar ambos enfoques.
Ejemplo: un pedido guarda los datos resumidos del usuario
(nombre, email) embebidos, pero tambi茅n su userId para futuras consultas.
{
_id: ObjectId("..."),
userId: ObjectId("..."),
user: { name: "Laura Garc铆a", email: "laura@gmail.com" },
items: [ { productId: ObjectId("..."), name: "Auriculares", qty: 2 } ],
total: 99.80
}
✅ Permite mostrar el pedido directamente sin hacer joins. 馃攧 Si el usuario cambia su nombre, el pedido hist贸rico sigue mostrando el nombre original.
6️⃣ Ejemplo pr谩ctico — dise帽o completo para tienda online
- users: datos personales + direcciones embebidas
- products: cat谩logo general
- orders: referencia al usuario + productos embebidos con datos de precio en el momento del pedido
- reviews: colecci贸n separada (crece mucho)
// users
{
name: "Laura",
email: "laura@gmail.com",
addresses: [
{ calle: "Gran V铆a 10", ciudad: "Madrid", cp: "28013" }
]
}
// products
{
name: "Auriculares",
sku: "AUR-01",
price: 49.90
}
// orders
{
userId: ObjectId("..."),
items: [
{ productId: ObjectId("..."), name: "Auriculares", price: 49.90, qty: 2 }
],
total: 99.80
}
// reviews
{
productId: ObjectId("..."),
userId: ObjectId("..."),
rating: 5,
text: "Excelente calidad"
}
7️⃣ Patrones de modelado comunes en MongoDB
- One-to-One: datos complementarios → embebidos o colecciones separadas seg煤n tama帽o.
- One-to-Many: pocos elementos → embebidos; muchos → referencias.
- Many-to-Many: usa arrays de referencias o colecci贸n intermedia.
- Subset pattern: almacenar solo parte de los datos (por ejemplo, 5 煤ltimos comentarios) y el resto en otra colecci贸n.
- Extended reference pattern: guardar en el documento los campos m谩s usados del documento referenciado.
8️⃣ Buenas pr谩cticas
- Evita documentos mayores a 16 MB (usa referencias o particiona datos).
- Agrega
createdAtyupdatedAta todos los documentos. - Usa
ObjectIdcomo ID por defecto. - Piensa en tus consultas m谩s comunes antes de dise帽ar las relaciones.
- Prefiere embebido para datos est谩ticos y de lectura frecuente.
- Prefiere referencia para datos compartidos o que cambian a menudo.
9️⃣ Ejemplo con Mongoose (estructura del modelo)
const mongoose = require("mongoose"); const ProductSchema = new mongoose.Schema({ name: String, sku: { type: String, unique: true }, price: Number, stock: Number }); const OrderSchema = new mongoose.Schema({ userId: mongoose.Schema.Types.ObjectId, items: [{ productId: mongoose.Schema.Types.ObjectId, name: String, price: Number, qty: Number }], total: Number, createdAt: { type: Date, default: Date.now } }); const Product = mongoose.model("Product", ProductSchema); const Order = mongoose.model("Order", OrderSchema);
馃攣 Resumen r谩pido
- Define tus consultas m谩s comunes.
- Embeber datos si siempre se usan juntos.
- Referenciar si los datos son grandes o compartidos.
- Combina ambos enfoques si es necesario (patr贸n mixto).
- Evita crecer documentos sin l铆mite → usa colecciones separadas.
0 Comentarios
Si desea contactar comigo, lo puede hacer atravez deste formulario gracias