Tengo esta estructura en mi modelo de Accounts :
{ cards: { starter: [], intermediate: [], advanced: [ {Object}, {Object}, {Object} ] }, firstName: 'Sepideh', email: 'sepideh@example.com', } Los Objects dentro de la matriz cards.advanced arriba son como:
{ cards: [ { // this is a single card object cardTitle: 'this card is for you', performance: [], cardID: 32, } ], unit: 3 // this is the unit we want to push our new card object into }Suponiendo que puedo acceder al documento anterior (o cuenta en otras palabras) con el correo electrónico dado:
const account = await db.Account.findOne({ email: 'sepideh@example.com' }); ¿Cómo podemos insertar un nuevo objeto de tarjeta en la matriz de tarjetas anidadas con la propiedad unit: 3 (sí, hasta ahora, esta es la única unidad) y guardar la cuenta de Sepideh de esta manera:
{ cards: { starter: [], intermediate: [], advanced: [ { cards: [ { // this is a single card object cardTitle: 'this card is for you', performance: [], cardID: 32, } { // this is new pushed card object cardTitle: 'this card is for me', performance: [], cardID: 33, } ], unit: 3 // this is the unit we want to push our new card object into }, {Object}, {Object} ] // end of advanced array }, firstName: 'Sepideh', email: 'sepideh@example.com', }He intentado seleccionar la unidad 3 del documento usando estos tipos y ninguno funcionó:
const userUnit = await account.findOne({'cards.advanced.unit': unit}); const userUnit = await account.findOne({'cards.advanced.unit': unit}); const userUnit = await account.find({}, {'cards.advanced.unit': {$elemMatch: {unit: unit}}}); const userUnit = await db.Account.findOne({ email: email, 'cards.advanced.unit': unit}); Luego empujaría mi nuevo objeto de tarjeta a la unidad de usuario y llamaría userUnit await account.save();
Lo único que funciona es un código JavaScript puro como este para seleccionar:
const userUnit = account.cards.advanced.find(e => e.unit == unit);Esta vez no puedo guardar los cambios en la base de datos... (No sé cómo guardarlo...)
¿Cómo harías esto?
Puede usar el operador$push directamente junto con el operador posicional $ que le permite especificar qué subelemento debe actualizarse:
await db.Account.update({ email: "sepideh@example.com", "cards.advanced.unit": 3 }, { $push: { "cards.advanced.$.cards": { cardTitle: 'this card is for me', performance: [], cardID: 33 } } })Si desea que su ruta se evalúe dinámicamente, puede usar nombres de propiedades computadas :
let path = "advanced"; await db.Account.update( { email: "sepideh@example.com", ["cards." + path + ".unit"]: 3 }, { $push: { ["cards." + path + ".$.cards"]: { cardTitle: 'this card is for me', performance: [], cardID: 33 } } })