mongodbmongoosemongodb-querymongodb-update

MongoDB - How to set the value of a field if it doesn't exist and remain the field if it is already presented in a document


So assume I have a document as shown below:

{
    "_id" : ObjectId("6336d94e0330f5d48e44fb0f"),
    "systemId" : "5124301",
    "userId" : "9876543210",
    "tempId" : "123456da87sdafasdf",
    "updatedAt" : ISODate("2022-09-30T12:01:11.714+0000"),
    "receivedAt" : ISODate("2022-04-10T23:15:08.145+0000"),
}

Now I already have a tempId assigned to the doc and sometimes that field might expire and not exist inside the document. I wanted to know if I'm updating the document with a different receivedAt parameter or any other parameter and it does not have a tempId then only assign it a tempId else let the tempId be as it is.

What should be the query for this to get the updated docs as given by two examples?

Case 1: If tempId exists:

{
    "_id" : ObjectId("6336d94e0330f5d48e44fb0f"),
    "systemId" : "5124301",
    "userId" : "1234567890",
    "tempId" : "123456da87sdafasdf",
    "updatedAt" : ISODate("2022-09-30T12:01:11.714+0000"),
    "receivedAt" : ISODate("2022-04-10T23:15:08.145+0000"),
}

Case 2: If there is no tempId and it is generated as "13qeqrwrqwtqrfsdfweqr" in the above line and document needs to be updated with the generated tempId.

{
    "_id" : ObjectId("6336d94e0330f5d48e44fb0f"),
    "systemId" : "5124301",
    "userId" : "1234567890",
    "tempId" : "13qeqrwrqwtqrfsdfweqr",
    "updatedAt" : ISODate("2022-09-30T12:01:11.714+0000"),
    "receivedAt" : ISODate("2022-04-10T23:15:08.145+0000"),
}

The query would be something like this:

findOneAndUpdate({
    systemId: "5124301"
},
{
    {
        $set: {
            userId: "1234567890",
            receivedAt : ISODate("2022-04-10T23:15:08.145+0000"),
            tempId: {
                      $exists: then leave it as is, else update it with 13qeqrwrqwtqrfsdfweqr
            }
        }
    }
})

Solution

  • Work with update with aggregation pipeline. Use $cond operator to check whether tempId is not equal ($ne) to undefined.

    If true, remain existing value $tempId.

    If false, assign value: "13qeqrwrqwtqrfsdfweqr".

    findOneAndUpdate({
      systemId: "5124301"
    },
    [
      {
        $set: {
          userId: "1234567890",
          receivedAt: ISODate("2022-04-10T23:15:08.145Z"),
          tempId: {
            $cond: {
              if: {
                $ne: [
                  "$tempId",
                  undefined
                ]
              },
              then: "$tempId",
              else: "13qeqrwrqwtqrfsdfweqr"
            }
          }
        }
      }
    ])
    

    Demo @ Mongo Playground