0

My Mongo schema looks like this, I want to update a flashcard object located in an array of flashcard also located in an array of subject.

const classrooms = new mongoose.Schema({
    name: String,
    year: String,
    student: [
        {
            firstname: String,
            lastname: String,
            mail: String,
            userId: String,
        }
    ],
    subject: [
        {
            subjectId: String,
            flashcard: [
                {
                    title: String,
                    tag: []
                }
            ]
        }
    ]
});

What I am doing is

const flashcard = await classroomModel.findOneAndUpdate({
    _id : classroomId,
    "subject" : {
        "subjectId" : subjectId,
        "subject.flashcard" : {
            "_id" : flashcardId
        }
    },
    "$set" : {
        "flashcard.title" : "new title"
    }
})

But this is deleting all flashcards located inside an object. Any help would be appreciated.

1
  • 1
    subject.flashcard does not have an _id field. It's an array of objects. Commented Nov 4, 2021 at 9:46

2 Answers 2

1

You need arrayFilters to specify the (to-be-updated) flashcard document that meets the criteria for subject and flashcard.

db.collection.update({
  _id: 1//classroomId,
  
},
{
  "$set": {
    "subject.$[subject].flashcard.$[flashcard].title": "new title"
  }
},
{
  arrayFilters: [
    {
      "subject.subjectId": 1//subjectId
      
    },
    {
      "flashcard._id": 1//flashcardId
      
    }
  ]
})

Sample Mongo Playground

Sign up to request clarification or add additional context in comments.

Comments

0

Although i accepted @yong shun which is the best approach, another way to do it in case you don't like mongoose syntax :


      const classroom = await classroomModel.findOne(
        {
          _id: 1 //classroomId,
        },
      )

      const subject = classroom.subject.find(
        (currentSubject: any) => {
          return currentSubject.subjectId == 1 //subjectId
        }
      )

      const flashcard = subject.flashcard.find(
        (currentFlashcard: any) => {
          return currentFlashcard._id == 1 //flashcardId
        }
      )
      flashcard.title = "my new title";
      await classroomModel.updateOne(classroom);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.