Vous devez fournir les multiples clés à $set
avec le positionnel $
opérateur
pour mettre à jour les deux clés correspondantes.
Je préfère la manière moderne de manipulation d'objets ES6 :
let params = { "_id" : "xxxproductid", "name" : "xxx", "img" : "yyy" };
let update = [
{ 'store.products._id': params._id },
{ "$set": Object.keys(params).filter(k => k != '_id')
.reduce((acc,curr) =>
Object.assign(acc,{ [`store.products.$.${curr}`]: params[curr] }),
{ })
}
];
User.update(...update,callback);
Ce qui produirait l'appel à MongoDB comme ( avec mongoose.set('debug', true)
) activé pour que nous voyions la requête :
Où fondamentalement vous prenez votre entrée params
et fournissez le _id
comme premier argument de la "query" :
{ 'store.products._id': params._id },
Le reste prend les "clés" de l'objet via Object.keys
qui fait un "tableau" que l'on peut "filtrer" avec Array.filter()
puis passez à Array.reduce
pour transformer ces clés en un Object
.
À l'intérieur du .reduce()
nous appelons Object.assign()
qui "fusionne" les objets avec les clés données, générées sous cette forme :
Object.assign(acc,{ [`store.products.$.${curr}`]: params[curr] }),
Utilisation de la syntaxe du modèle pour attribuer la "clé" "actuelle" (curr) au nouveau nom de clé, en utilisant à nouveau Syntaxe d'affectation de clé ES6 []:
qui autorise les noms de variables dans les littéraux d'objet.
L'objet "fusionné" résultant est renvoyé pour être affecté à l'objet "racine" où $set
est utilisé pour la clé de la mise à jour, donc les clés "générées" sont désormais des enfants de celle-ci.
J'utilise un tableau pour les arguments uniquement à des fins de débogage, mais cela permet également une syntaxe plus propre sur le réel .update()
en utilisant le "spread" ...
opérateur pour affecter les arguments :
User.update(...update,callback);
Propre et simple, et quelques techniques JavaScript que vous devriez apprendre pour la manipulation d'objets et de tableaux. Surtout depuis que la requête MongoDB DSL est essentiellement "Objets" et "Tableaux". Alors apprenez à les manipuler.