skip to Main Content

I have a structure like this:

{
  _id: new ObjectId("634aa49f98e3a05346dd2327"),
  filmName: 'Film number 1',
  episodes: [
    {
      episodeName: 'Testing 1',
      slugEpisode: 'testing-1',
      _id: new ObjectId("6351395c17f08335f1dabfc9")
    },
    {
      episodeName: 'Testing 2',
      slugEpisode: 'testing-2',
      _id: new ObjectId("6351399d9a2533b9be1cbab0")
    },
  ],
},
{
  _id: new ObjectId("634aa4cc98e3a05346dd232a"),
  filmName: 'Film number 2',
  episodes: [
    {
      episodeName: 'Something 1',
      slugEpisode: 'something-1',
      _id: new ObjectId("6367cce66d6b85442f850b3a")
    },
    {
      episodeName: 'Something 2',
      slugEpisode: 'something-2',
      _id: new ObjectId("6367cd0e6d6b85442f850b3e")
    },
  ],
}

I received 3 fields:

  • _id: Film _id
  • episodeId: Episode _id
  • episodeName: The content I wish to update

I tried to find a specific Film ID to get a specific film, and from then on, I pass an Episode ID to find the exact episode in the episodes array. Then, update the episodeName of that specific episode.

Here’s my code in NodeJS:

editEpisode: async (req, res) => {
    const { _id } = req.params
    const { episodeId, episodeName } = req.body

    try {
        const specificResult = await Films.findOneAndUpdate(
            { _id, 'episodes._id': episodeId },
            { episodeName }
        )

        console.log(specificResult)
        res.json({ msg: "Success update episode name" })
    } catch (err) {
        return res.status(500).json({ msg: err.message })
    }
},

But what console.log display to me is a whole document, and when I check in MongoDB, there was no update at all, does my way of using findOneAndUpdate incorrect?

I’m reading this document: MongooseJS – Find One and Update, they said this one gives me the option to filter and update.

2

Answers


  1. The MongoDB server needs to know which array element to update. If there is just one array element to update, here’s one way you could do it. (I picked a specific element. You would use your req.params and req.body.)

    db.films.update({
      "_id": ObjectId("634aa4cc98e3a05346dd232a"),
      "episodes._id": ObjectId("6367cd0e6d6b85442f850b3e")
    },
    {
      "$set": {
        "episodes.$.episodeName": "Something Two"
      }
    })
    

    Try it on mongoplayground.net.

    Login or Signup to reply.
  2. You can use the filtered positional operator $[<identifier>] which essentially finds the element or object (in your case) with a filter condition and updates that.

    Query:

    const { _id } = req.params
    const { episodeId, episodeName } = req.body
    
    await Films.update({
      "_id": _id
    },
    {
      $set: {
        "episodes.$[elem].episodeName": episodeName
      }
    },
    {
      arrayFilters: [
        {
          "elem._id": episodeId
        }
      ]
    })
    

    Check it out here for example purpose I’ve put ids as numbers and episode name to update as "UpdatedValue"

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search