Dus zoals je opmerkt, is de standaard in mangoest dat wanneer je gegevens "insluit" in een array als deze, je een _id
krijgt waarde voor elk matrixitem als onderdeel van zijn eigen subdocumenteigenschappen. U kunt deze waarde daadwerkelijk gebruiken om de index te bepalen van het item dat u wilt bijwerken. De MongoDB-manier om dit te doen is de positionele $
operatorvariabele, die de "overeenkomende" positie in de array bevat:
Folder.findOneAndUpdate(
{ "_id": folderId, "permissions._id": permission._id },
{
"$set": {
"permissions.$": permission
}
},
function(err,doc) {
}
);
Dat .findOneAndUpdate()
methode zal het gewijzigde document retourneren of anders kunt u gewoon .update()
. gebruiken als een methode als u het document niet wilt retourneren. De belangrijkste onderdelen zijn "matchen" met het element van de array dat moet worden bijgewerkt en "identificeren" die overeenkomen met de positionele $
zoals eerder vermeld.
Dan gebruik je natuurlijk de $set
operator zodat alleen de elementen die u opgeeft, worden feitelijk "over the wire" naar de server gestuurd. U kunt dit verder gaan met "puntnotatie" en gewoon de elementen specificeren die u daadwerkelijk wilt bijwerken. Zoals in:
Folder.findOneAndUpdate(
{ "_id": folderId, "permissions._id": permission._id },
{
"$set": {
"permissions.$.role": permission.role
}
},
function(err,doc) {
}
);
Dit is dus de flexibiliteit die MongoDB biedt, waarbij u zeer "gericht" kunt zijn in hoe u een document daadwerkelijk bijwerkt.
Wat dit echter wel doet, is alle logica die u in uw "mangoeste"-schema heeft ingebouwd "omzeilen", zoals "validatie" of andere "pre-save hooks". Dat komt omdat de "optimale" manier een MongoDB "functie" is en hoe deze is ontworpen. Mongoose probeert zelf een "gemak"-omhulsel te zijn over deze logica. Maar als je bereid bent om zelf enige controle te nemen, dan kunnen de updates op de meest optimale manier worden uitgevoerd.
Dus waar mogelijk om dit te doen, houdt u uw gegevens "embedded" en gebruikt u geen modellen waarnaar wordt verwezen. Het maakt de atomaire update van zowel "ouder" als "kind"-items mogelijk in eenvoudige updates waarbij u zich geen zorgen hoeft te maken over gelijktijdigheid. Dit is waarschijnlijk een van de redenen waarom u MongoDB in de eerste plaats had moeten selecteren.