MongoDB — documentos, no tablas.
Si en SQL los datos viven en filas con columnas fijas, en Mongo viven en documentos JSON que pueden anidar objetos, arrays, lo que quieras. Cada documento tiene su propia forma. La estructura no se declara antes — se descubre al insertar.
01Vocabulario que sí cambia
posts, users)._id. El equivalente de una fila, pero cada uno puede tener su propia forma.Un documento se ve así. Lo importante es que estos cuatro campos no están "predefinidos" en ningún lado — el motor los acepta al insertar:
{ _id: "p001", title: "Por qué empezar con SQL antes que NoSQL", author: "profesor_db", tags: ["sql", "tutorial"], stats: { views: 142, likes: 28 }, comments: [ { by: "ana", text: "Buenísimo!", likes: 3 }, { by: "luis", text: "¿Y cuándo Mongo?", likes: 1 } ] }
En SQL tendrías una tabla comments y un JOIN cada vez que muestras el post. En Mongo, mostrar el post completo es una sola lectura. Ese principio se llama embedding y es el corazón del diseño con documentos.
02CRUD — los cuatro verbos en Mongo
El shell de Mongo usa JavaScript. Aquí está la versión sin floritura:
// Insertar db.posts.insertOne({ title: "Hola", author: "ana", likes: 0 }) // Leer db.posts.find({ author: "ana" }) db.posts.findOne({ _id: "p001" }) // Actualizar db.posts.updateOne({ _id: "p001" }, { $set: { title: "Nuevo título" } }) // Borrar db.posts.deleteOne({ _id: "p001" })
Lo único "raro" al principio son los operadores con $. En el query sirven para comparar ($gt, $in…), en el update sirven para modificar ($set, $inc, $push…).
03Caso 1 · $push Blog con comentarios
Este es el ejemplo clásico donde Mongo brilla: un post con un array de comentarios anidado. Cuando alguien comenta, no insertas en otra tabla — haces $push al array del documento.
Escribe un comentario abajo y mira el documento entero a la derecha. Cada acción (comentar, dar like, borrar) imprime el comando Mongo exacto.
04Operadores de query — filtrar como pro
{ author: "ana" }. Para algo distinto: { author: { $ne: "ana" } }.$gt, $gte, $lt, $lte. { price: { $lte: 20000 } }.{ category: { $in: ["café","té"] } } es como WHERE … IN.$and, $or aceptan un array de condiciones.db.products.find({ category: { $in: ["café", "té"] }, price: { $lte: 20000 }, $or: [ { stock: { $gt: 0 } }, { tags: "premium" } ] })
05Caso 2 · find() Catálogo filtrable
Mueve los filtros de la izquierda y mira la query Mongo construirse en vivo a la derecha. Es exactamente lo que hace cualquier e-commerce moderno: cada filtro es un operador más en el objeto de búsqueda.
06Operadores de update
"address.city".$push pero evita duplicados — útil para tags, likers, etc.07Caso 3 · $set Editor de perfil
Aquí lo que importa es dot-notation: para cambiar la ciudad dentro de address, el campo se escribe "address.city". Mongo entiende el camino y solo modifica esa hoja, sin tocar el resto del objeto.
Un error común al empezar: updateOne({_id}, { newDoc }) sin $set. Eso reemplaza el documento entero — pierdes campos que no incluiste. Siempre usa los operadores ($set, $inc, $push) cuando quieras editar.
08Embedding vs Referencing
La gran decisión de diseño en Mongo es cuándo anidar y cuándo referenciar. La regla práctica:
- Embed cuando los datos hijos solo viven con su padre y se leen juntos: comentarios de un post, dirección de un usuario, items dentro de un pedido.
- Reference (un campo con el
_iddel otro) cuando los datos son independientes y se comparten: un usuario que aparece como autor en miles de posts no se duplica; guardas{ author_id: "u042" }. - Hay un límite duro: un documento no puede exceder 16 MB. Si el array crece sin parar, separa.
09Cuándo Mongo, cuándo NO Mongo
Mongo no es "SQL sin esquema". Es un modelo distinto donde tú diseñas los documentos en función de cómo se van a leer. Cuando lo entiendes, escribir CRUD es liberador. Cuando lo fuerzas a parecer una base relacional, sufres. Elige por la forma del problema, no por moda.