tengo este esquema:
... recommended:{ type:[{ movieId:String, recommendedBy:[String] }], default:[], }, name: { type: String, } de la solicitud obtengo movieId e id . Quiero agregar a la matriz recommended un nuevo objeto si ya no hay otro elemento con el mismo movieId allí, y agregar la id a la matriz anidada recommendedBy por en ambos casos.
hasta ahora tengo esto:
const user = User.findByIdAndUpdate({_id:'123'}, {$AddToSet:{'recommended.$[movie].recommendedBy':id}}, {arrayFilters:[{'movie.movieId':movieId}]}) esto solo establecerá el recommendedBy por un elemento ya existente con el mismo movieId , pero no insertará un nuevo objeto con la nueva propiedad movieId . (así que básicamente es $ AddToSet para ambas matrices) ¿Cómo podría lograr eso? ¡Gracias!
Tal vez necesite algo simple como esto que esté haciendo upsert o update para el elemento de matriz recomendado:
db.collection.update({}, [ { $set: { recommended: { "$reduce": { "input": "$recommended", "initialValue": // assign your edit data as init value [ { "movieId": "1", "recommendedBy": "who recommended" } ], "in": { "$cond": { "if": { $in: [ "$$this.movieId", "$$value.movieId" ] }, "then": "$$value", "else": { "$concatArrays": [ "$$value", [ "$$this" ] ] } } } } } } } ])explicado:
(Confirmado para trabajar en mongod 4.4)
No pude entender la respuesta de @ R2D2, así que se me ocurrió esta solución que funciona inesperadamente bien para mí, ya que también necesito poder eliminar el movieId y todo lo recommendedBy por él.
Cambié mi esquema a esto:
recommanded:{ type: Map, of:[String], default:{} },Estoy eliminando / agregando con:
User.findByIdAndUpdate({_id:"123",{$addToSet:{[`recommended.${movieId}`]:id}})Y
User.findByIdAndUpdate({_id:"123",{$unset:{[`recommended.${movieId}`]:""}})