en este curso se enseña de un modo base como hace un CRUD en MongooDB, y en la actualización de un documento. siempre se trabajo desde la raíz del documento. es decir algo asi:
{
_id: ObjectId:"akr1",
Company: "ZeroData"Phone: 1234567,,
addreess: "av limon ",
storage:"bodega 1"
}
si se fijan todo parte de la raíz del documento. es decir no hay documentos anidados, ni arrays de documentos.
por lo tanto hacer operaciones CRUD de esta forma es un tanto sencilla y los ejemplos que se dieron en el curso son validas.
pero… que pasa si la cosa se complica?
en el ejemplo anterior muestro como mi compañía llamada ‘ZeroData’ tiene una storage que se llama ‘bodega1’. con un par de datos mas como el teléfono.
pero todos sabemos que una compañía o empresa es mucho mas compleja… por lo tanto armemos un documento de una compañía real. probablemente con las que te vayas a topar en el ámbito laboral.
{
_id: ObjectId:"akr1",
Company: "ZeroData"
Phone: 1234567,,
addreess: {
addressName:"av limon",
commune: ObjectId("AJSDJASDE")
},
storage:[
{
_id:"ObjectId("dedsdsfsafrfas"),
nameStorage:"Bodega1",
addressStorage:{
addressName:"av vicuña limon",
commune:ObjectId("dsdadeedaed")
},
employees:[
{
_id:ObjectId("KSFRIN"),
rut:"2384328423-x",
name:"matias",
lastName:"aguilera",
}
]
}
phone:32332323
]
}
bueno ahora si tenemos algo mas complejo con lo que trabajar. si se fijan tenemos una compañía llamada “ZeroData” con un storage en forma de array de objetos. eso significa que puede tener ahora o en un futuro muchas bodegas.
por ahora solo cuenta con una bodega que tiene de nombre “bodega1” que tiene una dirección única que en este caso es “av vicuña limon” que se encuentra en la comuna del asociado al objectId (santiago).
esta bodega también cuenta con employees en forma de array de objetos. eso quiere decir que ahora o en un futuro puede tener muchos employees. sin embargo “bodega1” ahora solo cuenta con un employees que se llama “matias”
algo curioso es que nos damos cuenta que cada documento y subdocumentos tiene su _ID unico que representa a ese subdocumento. esto nos ayudara mas adelante.
bueno como podemos ver. ahora si podemos meter manos a la obra y hacer CRUD al documento de empresa…
pero hay un problema… y es que las consultas hechas en este curso quedan invalidas ante un problema asi.
por ejemplo:
si yo quisiera ingresar una nueva empresa pues no habria problema. sin embargo yo necesito ingresa solo los datos de la empresa.
porque no tengo ninguna bodega. en este caso storage quedaria vacio []
peroo y si… mas adelante quisiera agregar una ?
y si ahora quiero tener 2?
y si ahora quiero tener 3, pero que las 3 tengan datos reduntantes?
y que pasa si quiero agregar un nuevo empployees?
y si ahora quiero actualizar un storage porque habia un dato erroneo?
y si ahora quiero tener 3 employees?
te invito a probar resolver estas preguntas. con las misma funciones dadas en este curso para que veas su resultado,
lo hiciste? es importante no quedarse solo con la teoria y experimentar tu también con los datos.
bueno lo ideal es que busques resolver el problema tu pero al menos te mostrare la resolucion mia al problema de actualizar
functionaddUpdateStorage(id, storageDataUpdateStorage, idStorage) { //funcion que agrega un objeto de bodega nuevo al _id empresa asociadoreturnnew Promise(async (resolve, reject) => {
try {
if (idStorage) { //actualiza una bodega existente (WARNING): ACTUALIZA EL _IDawait model.updateOne({ '_id': { $eq: id } }, { $set: { 'storage.$[stor]': storageDataUpdateStorage } }, { arrayFilters: [{ "stor._id": { $eq: idStorage } }] })
await model.findOne({ _id: id })
.populate('address.commune')
.populate('storage.commune')
.populate('storage.employeesTechnical.technical')
.populate('storage.employeesAdmKreis.admKreis')//traemos el documento asociado al _id y poblamos todas las referencias a otras colleciones
.exec((error, populated) => { //ejecutamos el exec para que primero nos poble el modelo de de las referenciasif (error) {
return reject(`[addUpdateStorage] fallo en el FindOne ${error}`);
} else {
return resolve(populated); //retornamos el documento poblado
}
})
} else {
await model.findByIdAndUpdate(id, { $push: { 'storage': storageDataUpdateStorage } })//enivamos un nuevo objeto en el documento en base a la ruta storageawait model.findOne({ _id: id })
.populate('address.commune')
.populate('storage.commune')
//traemos el documento asociado al _id y poblamos todas las referencias a otras colleciones
.exec((error, populated) => { //ejecutamos el exec para que primero nos poble el modelo de de las referenciasif (error) {
return reject(`[addUpdateStorage] fallo en el FindOne ${error}`);
} else {
return resolve(populated); //retornamos el documento poblado
}
})
}
} catch (error) {
onError(`\n\n[addUpdateStorage]\n fallo en el Update: ${error} \n`, '[addUpdateStorage]', 'Linea de error:', '[addUpdateStorage]')
reject(`[addUpdateStorage] fallo en el store${error}`);
}
})
}
bueno bueno vayamos poco a poco. te invito a que analices el código.
si te fijas hay 2 cosas bien particulares así es…
lo primero es el
await model.updateOne()
y lo segundo es
await model.finByIdAndUpdate()
tu te preguntaras. pero… porque tienes 2 funciones para hacer una actualización dentro de un if ??
bueno pues lo primero es que hay 2 tipos de actualización . así es
1: actualización de agregación
2: actualización de modificación
la actualización de agregación es cuando tu quieres agregar un objecto a un documento ya existente.
en este caso yo quiero agregar una bodega a mi empresa.
la actualización de modificación es cuando yo quiero modificar un dato de mi bodega ya existente. obviamente sin que se modifiquen todas las demás.
vamos por la primera. que en este caso es el findByIdAndUpdate
await model.findByIdAndUpdate(id, { $push: { 'storage': storageDataUpdateStorage } })
primero que significa esta consulta. bueno te explico primero como lo dice la función, esta te busca el id y te lo actualiza.
pero OJO que esta función fusca solo el id de tu documento global. no documentos incrustados, es decir que tienes que buscar por el id de la empresa. recuerdas cual era? asi es
_id:ObjectId:"akr1"
bueno esta función acepta 3 parámetros
1- id
2 datos a actualizar
3-filtro (opcional)
si se fijan los parámetros los divido por una COMA, pero tu me preguntaras porque ves tantas llaves dentro del parámetro de la función. y es porque los 3 parametros requeridos tienen que ser OBJETOS
entonces se dividira asi
parametro 1
id //te busca por el id del documento global
parametro 2
{ $push: { 'storage': storageDataUpdateStorage } } //envio el documento de storage a actualizar
una pausa aqui. si se fijan el 2 parametro es un objeto pero dentro tiene otros objetos. bueno eso es posible.
pero que hace $push ?
bueno $push lo que hace es agregar un valor especificado a una matriz
pero a que matriz? bueno en el subObjeto lo detallo
{‘storage’: storageDataUpdateStorage}
pero que quiero decir aqui? bueno es simple te acuerdas de como se llama el atributo que contiene a la array de objetos de las bodegas?
asi es ‘storage’ a eso estoy haciendo referencia, entonces lo que hago es marcar que storage va a ser la raiz de donde insertare yo la actualizacion y lo ultimo es ya el objeto en si con los datos a actualizar