Du skal angive de flere nøgler til $set
med positionelle $
operatør
for at opdatere begge matchede nøgler.
Jeg foretrækker den moderne ES6 måde at manipulere objekter på:
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);
Hvilket ville producere kaldet til MongoDB som ( med mongoose.set('debug', true)
) slået til, så vi ser anmodningen:
Hvor du grundlæggende tager dit input params
og angiv _id
som det første argument for "forespørgslen" :
{ 'store.products._id': params._id },
Resten tager "nøglerne" fra objektet via Object.keys
som laver et "array", som vi kan "filtrere" med Array.filter()
og gå derefter til Array. reducere
at transformere disse nøgler til et Objekt
.
Inde i .reduce()
vi kalder Object.assign()
som "fletter" objekter med de givne nøgler, genereret i denne form:
Object.assign(acc,{ [`store.products.$.${curr}`]: params[curr] }),
Brug af skabelonsyntaksen til at tildele den "aktuelle" (curr) "nøgle" til det nye nøglenavn, igen ved at bruge ES6-nøgletildelingssyntaks []:
som tillader variabelnavne i objektliteral.
Det resulterende "merged" objekt sendes tilbage for at blive tildelt til "root" objektet, hvor $set
bruges til nøglen til opdateringen, så de "genererede" nøgler er nu børn af det.
Jeg bruger et array til argumenterne udelukkende til fejlfindingsformål, men så tillader det også renere syntaks på den faktiske .update()
ved hjælp af "spread" ...
operatør for at tildele argumenterne:
User.update(...update,callback);
Rent og enkelt, og nogle JavaScript-teknikker, som du bør lære til objekt- og array-manipulation. Mest da MongoDB-forespørgslen DSL dybest set er "Objekter" og "Arrays". Så lær at manipulere dem.