Home > Software design >  Mongoose modify/update objects inside and array
Mongoose modify/update objects inside and array

Time:12-13

I am new to MongoDB, and I am using mongoose for my schema. I want to update/modify a nested array from the schema, but I need help figuring out how to proceed with this.

Here is my schema :

const workoutSchema = new Schema(
  {
    dayName: {
      type: String,
      required: true
    },
    exercises: [
      {
        name: {
          type: String,
          required: true
        },
        sets: [
          {
            reps: {
              type: Number,
              required: true
            },
            weight: {
              type: Number,
              required: true
            }
          }
        ]
      }
    ]
  },
  { timestamps: true }
)

Here is the example data :

[
    {
        "_id": "6394d7b173d4d862b1124ced",
        "dayName": "Push Day",
        "exercises": [
            {
                "name": "Lat Pulldown",
                "sets": [
                    {
                        "weight": 40,
                        "_id": "6394d7db73d4d862b1124cf6"
                    },
                    {
                        "weight": 45,
                        "_id": "6394d7db73d4d862b1124cf7"
                    },
                    {
                        "weight": 45,
                        "_id": "6394d7db73d4d862b1124cf8"
                    }
                ],
                "_id": "6394d7db73d4d862b1124cf5"
            },
            {
                "name": "Deadlift",
                "sets": [
                    {
                        "reps": 5,
                        "weight": 65,
                        "_id": "6396e712ddd2681f1618922a"
                    },
                    {
                        "reps": 4,
                        "weight": 65,
                        "_id": "6396e712ddd2681f1618922b"
                    },
                    {
                        "reps": 4,
                        "weight": 65,
                        "_id": "6396e712ddd2681f1618922c"
                    }
                ],
                "_id": "6396e712ddd2681f16189229"
            }
        ],
        "createdAt": "2022-12-10T19:02:09.771Z",
        "updatedAt": "2022-12-12T08:32:17.996Z",
        "__v": 0
    }
]

exercises array can have multiple exercises. What I want is to first select the day (in this case Push Day and then add select the specific exercise (suppose Lat Pulldown in this case) and update a particular set in the exercises array. I am unable to figure out this. Can anyone point me in the right direction? Thanks for reading.

await WorkoutModel.findOneAndUpdate(
    { "exercises.sets._id": setId },
    { $set: { "exercises.$.sets": req.body } }
  )

I tried using this, but it's replacing the whole sets object rather than a single object.

CodePudding user response:

To modify or update objects inside an array in Mongoose, you can use the Model.updateMany() method, along with the $set operator and the $ positional operator. For example, if you have a model called BlogPost with a field called comments that contains an array of objects, you could use the following code to update a specific object in the array:

BlogPost.updateMany(
    { "comments._id": <id of the object to update> },
    { $set: { "comments.$.name": "New name" } }
)

In the above code, the $set operator is used to update the name field of the object in the comments array that has a matching _id field. The $ positional operator is used to specify which element in the comments array to update.

Alternatively, you can use the Model.findOneAndUpdate() method to update a single document that contains an array of objects. For example:

BlogPost.findOneAndUpdate(
    { "comments._id": <id of the object to update> },
    { $set: { "comments.$.name": "New name" } }
)

In this case, the findOneAndUpdate() method will find the first document that matches the query, and then update the specified object in the comments array. This method is useful if you only want to update a single document, rather than multiple documents as with the updateMany() method.

CodePudding user response:

You can use arrayFilters as follow:

db.collection.update({
"dayName": "Push Day",
"exercises.sets._id": "6394d7db73d4d862b1124cf6"
},
{
$set: {
 "exercises.$[y].sets.$[x]": {
  test: 1
  }
}
},
{
  arrayFilters: [
{
  "x._id": "6394d7db73d4d862b1124cf6"
 },
{
  "y.name": "Lat Pulldown"
 }
]
})

Playground

  • Related