Musíte dodat více klíčů pro $set
s poziční $
operátor
aktualizovat oba odpovídající klíče.
Preferuji moderní způsob manipulace s objekty 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);
Což by vyvolalo volání MongoDB jako (s mongoose.set('debug', true)
) zapnutý, takže vidíme požadavek:
Kde v podstatě vezmete své vstupní params
a zadejte _id
jako první argument pro "dotaz" :
{ 'store.products._id': params._id },
Zbytek si vezme „klíče“ od objektu přes Object.keys
což vytváří „pole“, které můžeme „filtrovat“ pomocí Array.filter()
a poté předejte do pole Array.reduce
transformovat tyto klíče na Object
.
Uvnitř .reduce()
nazýváme Object.assign()
který "sloučí" objekty s danými klíči, vygenerovanými v tomto tvaru:
Object.assign(acc,{ [`store.products.$.${curr}`]: params[curr] }),
Pomocí syntaxe šablony k přiřazení „aktuálního“ (curr) „klíče“ novému názvu klíče, opět pomocí Syntaxe přiřazení klíče ES6 []:
což umožňuje názvy proměnných v objektových literálech.
Výsledný "sloučený" objekt je předán zpět, aby byl přiřazen ke "kořenovému" objektu, kde $set
se používá pro klíč aktualizace, takže "vygenerované" klíče jsou nyní jeho potomky.
Používám pole pro argumenty čistě pro účely ladění, ale to také umožňuje čistší syntaxi skutečného .update()
pomocí "rozšíření" ...
operátor pro přiřazení argumentů:
User.update(...update,callback);
Čisté a jednoduché a některé techniky JavaScriptu, které byste se měli naučit pro manipulaci s objekty a poli. Většinou od dotazu MongoDB DSL je v podstatě „Objects“ a „Arrays“. Naučte se s nimi tedy manipulovat.