Necesito actualizar un campo anidado en mi documento de Usuario, que contiene una matriz de objetos de partes, para agregar nuevas partes. Un objeto parcial se ve así:
{ partId: 871838, partNum: '87087', partName: 'Brick Special 1 x 1 with Stud on 1 Side', colorId: 0, colorName: 'Black', quantity: 10, partImg: 'https:...' }Quiero agregar la parte a la matriz, pero solo si el usuario aún no la posee. Intenté usar $addToSet, así:
await User.updateOne( { username: username }, { $addToSet: { parts: { $each: req.body.parts } } } );pero eso no funcionará, ya que a veces la parte es la misma, pero la cantidad varía, y eso es suficiente para tratarla como una parte diferente, por lo que se agrega. ¿Hay alguna manera de especificar por qué valor determinar si el objeto ya existe en una matriz?
EDITAR: entonces, encontré esto en los documentos:
no puede especificar que MongoDB compare solo un subconjunto de los campos en el documento para determinar si el documento es un duplicado de un elemento de matriz existente
Entonces eso significa que $addToSet no es bueno para mi caso... Ahora no tengo idea de qué hacer.
Estoy publicando una respuesta, ya que logré obtener el resultado que quería, y me gustaría recibir comentarios. Funciona bien, pero se siente como fuerza bruta y un poco raro:
const incomingParts = req.body.parts; const _ownedParts = await User.findOne( { username: username }, { parts: 1, _id: 0 } ); let ownedParts: IPart[] = []; const newParts: IPart[] = []; //if statement for TS if (_ownedParts) { ownedParts = _ownedParts.parts; } let partsToAdd; if (ownedParts.length === 0) { //if the user owns no parts, just add the whole lot partsToAdd = [...req.body.parts]; } else { incomingParts.forEach((incoming: IPart) => { const ownedIdx = ownedParts.findIndex((owned: IPart) => { return incoming.partId === owned.partId; }); if (ownedIdx !== -1) { ownedParts[ownedIdx].quantity += incoming.quantity; } else { newParts.push(incoming); } }); partsToAdd = [...ownedParts, ...newParts]; } await User.updateOne( { username: username }, { $set: { parts: partsToAdd }, $push: { sets: setNum } } );Si hay una manera de usar operadores mongodb o agregados, me encantaría ver eso.
Si lo entiendo correctamente, desea cambiar un campo específico si la parte existe. Después de recibir los cheques, puede consultar esto:
await User.updateOne( { username: username }, { $set: { "parts.0.partNum": 234234 } );Eso suponiendo que conozca el índice de la parte específica. Puede usar esto como referencia: https://docs.mongodb.com/manual/reference/operator/update/set/