Search code examples
node.jsmongodbmui-x-data-grid

How do I update a specific array of objects in a document's array


The document is as follows:

{
  "_id": {
    "$oid": "64f832a51e7647d451ea8daa"
  },
  "requisitionOpenDate": "6/9/2023/ 13:34:37",
  "requisitionId": 33280,
  "requestorName": "Amar",
  "requestorEmail": "[email protected]",
  "projectSbu": "1",
  "projectStage": "2",
  "projectCompetency": "1",
  "projectCodeCreated": "1",
  "projectCode": 12345,
  "salesforceId": 12345,
  "resourceDetails": [
     {
       "rowid": "025820850bb6-7408257gh9",
       "level": "Beginner",
       "experience": 6,
       "location": "Maine",
       "_id": "...."
     },
     {
       "rowid": "72504385254mm7-74238474hj4",
       "level": "Advanced",
       "experience": 7,
       "location": "Vienna",
       "_id": "...."
     }
  ],
  "__v": 0
}

I want to update the rowid: "025820850bb6-7408257gh9", to have the following details:

     {
       "rowid": "025820850bb6-7408257gh9",
       "level": "Rookie",
       "experience": 6.3,
       "location": "Vancouver",
       "_id": "...."
     }

And if the rowid doesn't exist, I want to add it as a new object. I'm trying to write this logic in my Nodejs api, and can't figure this out. Would appreciate the help.

Note: The rowid is something that I'm receiving from MUI/x-data-grid, it isn't the same as "_id" given by MongoDB.


Solution

  • You could do something as follow :

    1. Match the document you want to update
    2. Check if rowid exists. If so, merge the corresponding nested object with your wanted object. Else, add your object at the end.
    db.collection.update({
      "_id": {
        "$oid": "64f832a51e7647d451ea8daa"
      }
    },
    [
      {
        "$set": {
          "resourceDetails": {
            "$cond": {
              if: {
                $in: [
                  "025820850bb6-7408257gh9",
                  {
                    "$ifNull": [
                      "$resourceDetails.rowid",
                      []
                    ]
                  }
                ]
              },
              then: {
                $map: {
                  input: "$resourceDetails",
                  in: {
                    $cond: {
                      if: {
                        $eq: [
                          "$$this.rowid",
                          "025820850bb6-7408257gh9"
                        ]
                      },
                      then: {
                        $mergeObjects: [
                          "$$this",
                          {
                            "rowid": "025820850bb6-7408257gh9",
                            "level": "Rookie",
                            "experience": 6.3,
                            "location": "Vancouver",
                            "_id": "...."
                          }
                        ]
                      },
                      else: "$$this"
                    }
                  }
                }
              },
              else: {
                "$concatArrays": [
                  {
                    $ifNull: [
                      "$resourceDetails",
                      []
                    ]
                  },
                  [
                    {
                      "rowid": "025820850bb6-7408257gh9",
                      "level": "Rookie",
                      "experience": 6.3,
                      "location": "Vancouver",
                      "_id": "...."
                    }
                  ]
                ]
              }
            }
          }
        }
      }
    ])
    

    You can test it here MongoPlayground