2 votes

Mongoose : mettre à jour un élément dans un tableau json

Je tente de mettre à jour un document utilisateur qui ressemble à ceci :

{
_id:"xyzdon'tcare",
username:"john",
examTrials:Array[
    {
        trialId:"x1",
        examId:"y",
        questions:Array[
            {ques1 Object},
            {ques2 object}
        ]
    },
    {
        trialId:"x2",
        examId:"z",
        questions:Array[
            {ques1 Object},
            {ques2 object}
        ]
    }]
}

J'ai essayé la manière la plus directe, findOne() puis modifier le document puis save(). Le problème est que j'ai rencontré des problèmes de condition de course avec les versions du document quand une nouvelle demande est arrivée avant la fin de la mise à jour précédente.

Maintenant j'essaye d'utiliser findOneAndUpdate() pour mettre à jour un objet question à l'intérieur du tableau de questions dans un essai spécifique et je n'arrive pas à comprendre comment faire cela.

Les informations que j'ai :

  • Id de l'essai
  • objet question
  • Id de la question

Je pense que c'est tout ce dont j'ai besoin. Des conseils ?

------------ EDIT

app.post('/updatetrialsession',authenticateJWT ,(req,res)=>{
        User.findOneAndUpdate({
        username: req.user.username
      }, {
           $set: {'examTrials.$[elem1].questions.$[elem2]' : req.body.question,
                'examTrials.$[elem1].currentQuestion':req.body.questionIdx+1 }
      }, {
           arrayFilters: [{'elem1.trialId': req.body.trialId }, {'elem2': req.body.questionIdx}]
      }).then(res=>{
          console.log("mis à jour")
      })
})

currentQuestion a été mis à jour, mais l'objet question ne l'a pas été.

1voto

Mahan Points 612

Vous pouvez utiliser mongoose arrayFilter pour mettre à jour un champ dans un tableau.

Par exemple, si vous avez userId pour interroger votre utilisateur, trialId pour interroger votre essai d'examen, questionId pour interroger votre question, et newQuestionObject comme mise à jour de la question, ce code fera le travail pour vous :

User.findOneAndUpdate({
  _id: userId
}, {
     $set: {'examTrials.$[elem1].questions.$[elem2]' : newQuestionObject}
}, {
     arrayFilters: [{'elem1.trialId': trialId}, {'elem2': questionId}]
});

Ou si vous voulez mettre à jour un champ spécifique de l'objet de question, vous pouvez simplement le faire comme ceci :

User.findOneAndUpdate({
  _id: userId
}, {
     $set: {'examTrials.$[elem1].questions.$[elem2].status' : 'newStatus'}
}, {
     arrayFilters: [{'elem1.trialId': trialId}, {'elem2': questionId}]
});

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X