Join us at MongoDB.local London on 7 May to unlock new possibilities for your data. Use WEB50 to save 50%.
Register now >
Docs Menu
Docs Home
/ /

Tutorial: Mongoose comenzar

Mongoose es una librería de Modelado de Datos de Objetos (ODM) para MongoDB. Puedes usar Mongoose para facilitar el modelado de datos, la aplicación del esquema, la validación de modelos y la manipulación general de datos. Como MongoDB tiene un modelo de datos flexible que te permite modificar y actualizar bases de datos en el futuro, no hay esquemas rígidos. Sin embargo, Mongoose aplica un esquema semi rígido desde el principio, por lo que se debe definir un esquema y un modelo.

Un esquema define la estructura de los documentos de la colección. Un esquema de Mongoose se asigna directamente a una colección de MongoDB.

El siguiente ejemplo crea un nuevo esquema llamado blog:

const blog = new Schema({
title: String,
slug: String,
published: Boolean,
author: String,
content: String,
tags: [String],
comments: [{
user: String,
content: String,
votes: Number
}]
}, {
timestamps: true
});

Al crear un esquema, debe definir cada campo y sus tipos de datos. Se permiten los siguientes tipos:

  • String

  • Número

  • fecha

  • Buffer

  • Booleano

  • Mezclado

  • ObjectId

  • Arreglo

  • Int32

  • Decimal128

  • Double

  • Map

Los modelos toman su esquema y lo aplican a cada documento en su colección. Los modelos son responsables de todas las interacciones con documentos, como las operaciones de creación, lectura, actualización y eliminación (CRUD).

Tip

El primer argumento que pasas al modelo es la forma singular del nombre de tu colección. Mongoose cambia esto automáticamente a la forma plural, lo transforma a minúsculas y utiliza eso para el nombre de la colección de la base de datos.

El siguiente ejemplo muestra cómo declarar un modelo llamado Blog que utiliza el esquema blog:

const Blog = mongoose.model('Blog', blog);

En el ejemplo anterior, Blog se traduce a la colección blogs en MongoDB.

En este tutorial, realizarás las siguientes acciones:

  • Configura tu entorno para usar Mongoose

  • Conéctese a MongoDB

  • Crea un esquema y modelo de Mongoose

  • Insertar, actualizar, buscar y borrar datos

  • Campos del documento del proyecto

  • Valida tus datos

  • Utiliza múltiples esquemas y middleware

1

Antes de empezar este tutorial, asegúrate de tener preparados los siguientes componentes:

  • Una cuenta de MongoDB Atlas con un clúster configurado. Para ver las instrucciones, consulte MongoDB Get Started guía.

  • Node.js v16.20.1 o después.

2

Este tutorial usa nodemon para ejecutar el código localmente. Ejecute los siguientes comandos en su terminal para inicializar su proyecto e instalar las dependencias necesarias:

mkdir mongodb-mongoose
cd mongodb-mongoose
npm init -y
npm i mongoose
npm i -D nodemon

Abre tu proyecto en tu editor de código preferido. Este tutorial utiliza módulos ES en lugar de CommonJS. Debes añadir el tipo module para usar módulos ES. Ve al archivo package.json y añade el siguiente código:

...
"scripts": {
"dev": "nodemon index.js"
},
"type": "module",
...

Inicie su aplicación con nodemon ejecutando el siguiente comando:

npm run dev

Nota

Cuando usas nodemon, el código se ejecuta cada vez que guardas un archivo.

3

En el nivel raíz de tu proyecto, crea un archivo llamado index.js y añade el siguiente código al principio del archivo:

import mongoose from 'mongoose';
mongoose.connect("<connection string>")

Reemplace el marcado de posición <connection string> con su cadena de conexión de MongoDB Atlas. Para obtener más información sobre cómo encontrar su cadena de conexión, consulte el tutorial Conectarse a su clúster en la documentación de Atlas.

4

Antes de empezar a agregar y actualizar datos en MongoDB, primero debes crear un esquema y un modelo.

Con Mongoose, creas un archivo de modelo de esquema para cada esquema que se necesite. Primero, cree una carpeta llamada model para guardar todos los archivos de su esquema y, luego, cree su primer archivo de esquema llamado Blog.js. Abre este archivo y añade el siguiente código:

import mongoose from 'mongoose';
const { Schema, model } = mongoose;
const blogSchema = new Schema({
title: String,
slug: String,
published: Boolean,
author: String,
content: String,
tags: [String],
comments: [{
user: String,
content: String,
votes: Number
}]
}, {
timestamps: true
});
const Blog = model('Blog', blogSchema);
export default Blog;

Este esquema permite una opción timestamps que añade los campos createdAt y updatedAt gestionados por mongoose al esquema, los cuales se actualizan automáticamente. Para obtener más información, consulta la página de Sello de tiempo en la documentación de Mongoose.

5

Ahora que tienes tu primer modelo y esquema configurados, puedes empezar a insertar datos en la base de datos. Las siguientes secciones muestran cómo realizar operaciones CRUD utilizando Mongoose.

Vaya a index.js y agregue la siguiente declaración de importación en la parte superior de su archivo:

import Blog from './model/Blog.js';

Agregue el siguiente código debajo de la línea que contiene su cadena de conexión:

// Creates a new blog post and inserts it into database
const article = await Blog.create({
title: 'Awesome Post!',
slug: 'awesome-post',
published: true,
content: 'This is the best post ever',
tags: ['featured', 'announcement'],
});
console.log('Created article:', article);

El código anterior utiliza el método Mongoose create() para crear el objeto que representa un artículo de blog y luego lo guarda en la base de datos. El documento devuelto se registra en la consola, incluyendo su _id. Toma nota de este _id para usarlo en futuros pasos.

Para actualizar datos, puedes editar directamente el objeto local con Mongoose. Luego, puedes usar el método save() para guardar la actualización en la base de datos.

Agregue el siguiente código para actualizar el artículo que insertó en la sección anterior:

// Updates the title of the article
article.title = "The Most Awesomest Post!!";
await article.save();
console.log('Updated Article:', article);
Updated Article: {
title: 'The Most Awesomest Post!!',
slug: 'awesome-post',
published: true,
content: 'This is the best post ever',
tags: [ 'featured', 'announcement' ],
_id: new ObjectId('...'),
comments: [],
__v: 0
}

Para encontrar un documento específico, puede utilizar el método Mongoose findById() para consultar un documento especificando su _id.

Agregue el siguiente código a su archivo index.js para encontrar un artículo específico por su _id:

// Finds the article by its ID. Replace <object id> with the objectId of the article.
const articleFound = await Blog.findById("<object id>").exec();
console.log('Found Article by ID:', articleFound);
Found Article by ID: {
_id: new ObjectId('68261c9dae39e390341c367c'),
title: 'The Most Awesomest Post!!',
slug: 'awesome-post',
published: true,
content: 'This is the best post ever',
tags: [ 'featured', 'announcement' ],
comments: [],
__v: 0
}

Nota

Por defecto, las Mongoose queries devuelven "thenables", que son objetos con algunas propiedades de una JavaScript Promise. Puede agregar el método exec() a una query para recibir una verdadera JavaScript Promise. Para obtener más información sobre cómo trabajar con promesas en Mongoose, consulta la Guía de promesas en la documentación de Mongoose.

Puede usar Mongoose para proyectar solo los campos que necesita. El siguiente código especifica que solo se proyecten los campos title, slug y content.

Agrega el siguiente código a tu archivo index.js, reemplazando el marcador de posición <object id> con el valor ObjectId del documento que has insertado previamente:

// Finds the article by its ID and projects only the title, slug, and content fields.
// Replace <object id> with the objectId of the article.
const articleProject = await Blog.findById("<object id>", "title slug content").exec();
console.log('Projected Article:', articleProject);
Projected Article: {
_id: new ObjectId('...'),
title: 'The Most Awesomest Post!!',
slug: 'awesome-post',
content: 'This is the best post ever'
}

Mongoose usa los métodos deleteOne() y deleteMany() para borrar datos de una colección. Puedes especificar el campo del documento que deseas borrar y pasar ese campo al método que elijas.

Agrega el siguiente código a tu archivo index.js para borrar un artículo de la base de datos:

// Deletes one article with the slug "awesome-post".
const blogOne = await Blog.deleteOne({ slug: "awesome-post" });
console.log('Deleted One Blog:', blogOne);
Deleted One Blog: { acknowledged: true, deletedCount: 1 }

Para eliminar varios artículos, puede agregar el siguiente código:

// Deletes all articles with the slug "awesome-post".
const blogMany = await Blog.deleteMany({ slug: "awesome-post" });
console.log('Deleted Many Blogs:', blogMany);
Deleted Many Blogs: { acknowledged: true, deletedCount: 4 }
6

Los artículos insertados en los pasos anteriores no contienen los campos author, dates o comments, aunque estos campos estén incluidos en el esquema. Esto se debe a que, si bien ha definido la estructura de su documento, no ha definido qué campos son obligatorios. Se puede omitir cualquier campo que no se defina como obligatorio.

En Mongoose, cuando se incluye una validación en un campo, se debe pasar un objeto como su valor.

Nota

Los validadores se ejecutan automáticamente en los métodos create() y save(). Puedes especificar que se ejecuten en métodos de actualización, como update() y updateOne(), configurando la opción runValidators en true. Para obtener más información sobre los validadores, consulta la página Validación en la documentación de Mongoose.

Puedes utilizar varios métodos de validación con Mongoose. Por ejemplo, puedes establecer required en verdadero en cualquier campo que desees hacer obligatorio. También puedes validar el tipo y el formato. En el siguiente código, el campo slug se define como un string con un minLength de 4. Esto significa que proporcionar un slug con menos de 4 caracteres resultará en un ValidationError.

Para agregar validación de datos y definir estos requerimientos, actualiza el esquema en Blog.js como se muestra en el siguiente ejemplo:

const blogSchema = new Schema({
title: {
type: String,
required: true,
},
slug: {
type: String,
required: true,
minLength: 4,
},
published: {
type: Boolean,
default: false,
},
author: {
type: String,
required: true,
},
content: String,
tags: [String],
comments: [{
user: String,
content: String,
votes: Number
}]
}, {
timestamps: true
});

Después de añadir esta validación, su aplicación se bloqueará. Agregue un campo author a la llamada create() en su archivo index.js para cumplir con el nuevo requisito de validación:

// Creates a new blog post and inserts it into database
const article = await Blog.create({
title: 'Awesome Post!',
slug: 'awesome-post',
published: true,
author: 'A.B. Cee',
content: 'This is the best post ever',
tags: ['featured', 'announcement'],
});

Tip

Cuando usas esquemas con Mongoose, value: String es igual que value: {type: String}.

Para obtener más información, consulte la página Validación en la documentación de Mongoose.

7

A continuación, puedes agregar más complejidad a tu campo author creando otro esquema e incluyéndolo en el esquema del blog.

En la carpeta model, crea un archivo nuevo llamado User.js. Agregue el siguiente código a este archivo:

import mongoose from 'mongoose';
const {Schema, model} = mongoose;
const userSchema = new Schema({
name: {
type: String,
required: true,
},
email: {
type: String,
minLength: 10,
required: true,
lowercase: true
},
});
const User = model('User', userSchema);
export default User;

Para utilizar su nuevo modelo de usuario para definir el campo author en el esquema del blog, actualice el archivo Blog.js con los siguientes cambios:

  • Agrega SchemaTypes a la lista de propiedades extraídas de la librería Mongoose.

  • Cambia el campo author type a SchemaTypes.ObjectId y añade una referencia (ref) al modelo 'User'.

El siguiente código muestra estas actualizaciones:

const { Schema, SchemaTypes, model } = mongoose;
... // Inside Schema block:
author: {
type: SchemaTypes.ObjectId,
ref: 'User',
required: true,
},
...

Puede reutilizar el mismo modelo User para el campo comment.user cambiando la definición blogSchema:

... // Inside Schema block:
comments: [{
user: {
type: SchemaTypes.ObjectId,
ref: 'User',
required: true,
},
...

Para usar el nuevo modelo de usuario en su aplicación, vaya al archivo index.js. Agregue el siguiente código al principio del archivo para importar el modelo de usuario:

import User from './model/User.js';

Debido a que agregó la validación de campo al esquema del blog, el código anterior para insertar, actualizar y eliminar blogs, y para especificar campos para proyectar, no pasará la validación y la aplicación generará un error.

Cree un nuevo usuario agregando la siguiente llamada create():

// Create a new user
const user = await User.create({
name: 'Jess Garica',
email: 'jgarcia@email.com',
});

Actualiza la llamada existente create() con el siguiente código para crear un nuevo artículo que utilice al nuevo usuario como autor, como se muestra en el siguiente código:

// Creates a new blog post that references the user as the author
const articleAuthor = await Blog.create({
title: 'Awesome Post!',
slug: 'Awesome-Post',
author: user._id,
content: 'This is the best post ever',
tags: ['featured', 'announcement'],
});
console.log('Article with Author:', articleAuthor);
Article with Author: {
title: 'Awesome Post!',
slug: 'awesome-post',
published: false,
author: new ObjectId('...'),
content: 'This is the best post ever',
tags: [ 'featured', 'announcement' ],
_id: new ObjectId('...'),
createdAt: 2025-05-15T18:05:23.780Z,
comments: [],
__v: 0
}

El código anterior añade una colección users con la colección blogs en la base de datos MongoDB. Este código agrega el campo requerido author y establece su valor en el user._id.

Para añadir los valores de los campos name y email al campo author del artículo, puede adjuntar el método populate() de Mongoose a su consulta de Blog. El método populate() realizará una segunda query para el documento de Usuario referido por user._id.

Agregue el siguiente código a index.js para completar estos datos:

// Populates the author field with user data
const articlePopulate = await Blog.findOne({ title: "Awesome Post!" }).populate("author");
console.log('Article Populated:', articlePopulate);
Article Populated: {
_id: new ObjectId('...'),
title: 'Awesome Post!',
slug: 'awesome-post',
published: false,
author: {
_id: new ObjectId('...'),
name: 'Jess Garica',
email: 'jgarcia@email.com',
__v: 0
},
content: 'This is the best post ever',
tags: [ 'featured', 'announcement' ],
createdAt: 2025-05-15T18:04:28.590Z,
comments: [],
__v: 0
}

Para obtener más información, consulte la página Document.populate() de la documentación de la API de Mongoose.

8

En Mongoose, los middleware son funciones que se ejecutan antes o durante la ejecución de funciones asíncronas a nivel de esquema.

Un ejemplo de middleware es una función que valida el campo email de una instancia de User antes de guardar o actualizar.

Este ejemplo utiliza el paquete validator. Puedes instalar el paquete validator ejecutando el siguiente comando:

npm install validator

Para añadir esta función de middleware, añade el siguiente código a la declaración userSchema en tu archivo User.js:

import validator from 'validator';
userSchema.pre('save', function (next) {
const user = this;
// Normalize email
if (user.email) {
user.email = user.email.trim().toLowerCase();
}
// Validate email format
if (!validator.isEmail(user.email)) {
return next(new Error('Invalid email format'));
}
next();
});

Para ver el efecto de esta función, modifica el campo user.email en tu archivo index.js para convertirlo en una dirección de correo electrónico no válida:

const user = await User.create({
name: 'Jess Garica',
email: 'jgarciaemail.com',
});
Error: Invalid email format

Si corriges la dirección de correo electrónico, puedes ver que no se produce el error.

Además de la pre() función de middleware, Mongoose también ofrece la post() función. Para más información sobre middleware, consulte la página de middleware en la documentación de Mongoose.

Ahora tienes un proyecto de ejemplo que utiliza Mongoose para realizar operaciones CRUD en una colección de MongoDB. Desde aquí, puedes optar por compilar sobre este Proyecto con queries más complejas o validación de documentos. Las siguientes secciones incluyen algunos ejemplos de las funcionalidades de Mongoose que podría utilizar en su aplicación.

Los setters personalizados modifican tus datos cuando se guardan y pueden implementarse de manera similar a los validadores. Mongoose proporciona los siguientes setters personalizados:

  • lowercase

  • uppercase

  • trim

El siguiente ejemplo convierte a minúsculas los caracteres del campo blog.slug:

const blogSchema = new Schema({
...
slug: {
type: String,
required: true,
minLength: 4,
lowercase: true,
},
...
});

Para más información, consulta la página de SchemaStringOptions en la documentación de la API de Mongoose.

Mongoose incluye varios métodos asistentes que están abstraídos de los métodos regulares de MongoDB. En esta sección, puedes encontrar ejemplos de algunos de estos métodos. Estos métodos no se utilizan específicamente en este tutorial, pero son útiles para consultarlos cuando se comienza a usar Mongoose.

El método exists() devuelve null o el primer documento que coincide con la query proporcionada. El siguiente es un ejemplo de coincidencia de un artículo en función del campo author:

const blog = await Blog.exists({ author: 'Jess Garcia' });
console.log(blog);

Para obtener más información, consulte la sección Model.exists() de la documentación de la API de Mongoose.

El método where() permite encadenar y compilar consultas complejas.

Ejemplo de operación de búsqueda utilizando findOne() con un objeto de query simple y la query equivalente con el método where():

const blogFind = await Blog.findOne({ author: "Jess Garcia" });
console.log(blogFind);
const blogWhere = await Blog.findOne().where("author").equals("Jess Garcia");
console.log(blogWhere);

En esta implementación, la implementación de where() comienza con un findOne() que indica a Mongoose que lo trate como una query findOne(). Esto es importante porque si usas where() por sí solo (Blog.where(...)), Mongoose lo trata implícitamente como una operación find().

Generalmente, el método where() se utiliza para queries complejas que implican la creación dinámica de queries o múltiples comparadores, o cuando el uso de este método mejora la legibilidad. No existe diferencia de rendimiento entre utilizar el método where() o una query de objeto simple.

Para incluir la proyección al utilizar el método where(), encadene el método select() después de su query, como se muestra en el siguiente ejemplo:

const blog = await Blog.findOne().where("author").equals("Jess Garcia").select("title author");
console.log(blog);

Para obtener más información, consulta las siguientes secciones de la documentación de la API de Mongoose:

Para aprender más sobre cómo utilizar Mongoose con MongoDB, consulta la Documentación de Mongoose.

Para encontrar soporte o contribuir a la comunidad de MongoDB, consulte la página de MongoDB Developer Community.

Volver

Integra con Mongoose

En esta página