# Mongoose
## Instalación
```bash
npm i mongoose
```
## Crear una conexión
Lo impartante es modificar la URL de conexión reemplazando `<host>`, `<port>` y `<database>` por las que necesitemos, si no se especifica el puerto utilizará por default el puerto `27017`.
```javascript
var mongoose = require('mongoose');
mongoose.connect('mongodb://<host>:<port>/<database>', {
useNewUrlParser: true,
useUnifiedTopology: true,
useCreateIndex: true
});
```
## Definición de Schemas
Un `schema` es la definición de nuestro documento, por ejemplo, si queremos hacer la representación de un usuario con los siguientes campos y restricciones:
- `nombre`: Obligatorio, tipo `string`
- `correo`: Obligatorio, único, tipo `string`
- `apellidoPaterno`: Tipo `string`
- `apellidoMaterno`: Tipo `string`
Lo podemos representar de la siguiente forma:
```javascript
var Schema = mongoose.Schema;
const UserSchema = new Schema({
nombre: { type: String, required: true },
correo: { type: String, required: true, unique: true },
apellidoPaterno: { type: String },
apellidoMaterno: { type: String }
}, { collection: 'users' });
```
Es importante notar, que no sólo agregamos los campos y su definición, como tipo, restricciones, etc. Además hay que agregar el nombre de la colección en la base de datos, en nuestro ejemplo se llama `collection: 'users'`
**Más detalle en:** [Mongoose guides - schema types](https://mongoosejs.com/docs/schematypes.html)
## Modelos
Un términos "coloquiales" un modelo es el responsable de crear y leer documentos a partir de un `schema`
Tomando como base el schema anterior `UserSchema`, podemos generar su modelo de la siguiente forma
```javascript
let UserModel = mongoose.model('users', UserSchema);
```
**Más detalle en:** [Mongoose guides - models](https://mongoosejs.com/docs/models.html)
## Save
```javascript
let instance = new UserModel({
nombre: 'Luis',
correo: 'luis@domain.com',
apellidoPaterno: 'Zamudio',
apellidoMaterno: 'Cervantes'
});
instance.save();
```
## Update
Para actualizar uno o más documentos, podemos utilizar dos método `updateOne` y `updateMany` donde las diferencias pueden ser "obvias", es decir, si queremos actualizar **solo un documento** deberíamos de usar el método `updateOne`, en caso contrario, si lo que queremos es actualizar **uno o más documentos** deberíamos utilizar el documento `updateMany`. En ambos métodos debemos de pasar 2 parámetros, el primero es el **filter**. Un **filter** es un objeto que contiene las condiciones para buscar un documento, por ejemplo, si queremos actualizar el campo `nombre` de la colección que tiene `correo = 'luis@domain.com'` el **filter** a utilizar sería: `{ correo: 'luis@domain.com' }`. El segundo parámetro es un objeto que contiene los campos y sus valores que serán actualizados.
Por ejemplo, si queremos actualizar al usuario que tiene por nombre `Luis` por `Luis Enrique` deberíamos de hacer lo siguiente:
```javascript
UserModel.updateOne({ nombre: 'Luis' }, { $set: { nombre: 'Luis Enrique'}} )
.then( result => console.log(result))
.catch(error => console.log(error));
```
```javascript
UserModel.updateMany({ nombre: 'Luis' }, { $set: { nombre: 'Luis Enrique'}} )
.then( result => console.log(result))
.catch(error => console.log(error));
```
**Más detalles en:**
[Mongoose `Model.updateMany()`](https://mongoosejs.com/docs/api.html#model_Model.updateMany)
[Mongoose `Model.updateOne()`](https://mongoosejs.com/docs/api.html#model_Model.updateOne)
## Buscar
De la misma forma que en el método `update`, tenemos 2 métodos disponibles para realizar busquedas en nuestra coleccion.
El método `findOne` regresa **solo un objeto** o `null` si no escuentra algúna coincidencia
```javascript
UserModel.findOne({ nombre: 'Luis'})
.then( result => console.log(result))
.catch(error => console.log(error));
```
El método `find` regresa **un arreglo de objetos** o un arreglo vacío si no escuentra algúna coincidencia.
```javascript
UserModel.find({ nombre: 'Luis' })
.then( result => console.log(result))
.catch(error => console.log(error));
```
**Más detalles en:**
[Mongoose `Model.findOne()`](https://mongoosejs.com/docs/api.html#model_Model.findOne)
[Mongoose `Model.find()`](https://mongoosejs.com/docs/api.html#model_Model.find)
## Borrar
El método `deleteOne` elimina **solo un objeto** que coincida con el `filter` propocionado
```javascript
UserModel.deleteOne({ nombre: 'Luis' })
.then( result => console.log(result))
.catch(error => console.log(error));
```
El método `deleteOne` elimina **solo un objeto** que coincida con el `filter` propocionado
```javascript
UserModel.deleteMany({ nombre: 'Luis' })
.then( result => console.log(result))
.catch(error => console.log(error));
```
**Más detalles en:**
[Mongoose `Model.deleteOne()`](https://mongoosejs.com/docs/api.html#model_Model.deleteOne)
[Mongoose `Model.deleteMany()`](https://mongoosejs.com/docs/api.html#model_Model.deleteMany)