hantoren
hantoren

Reputation: 1225

Update element in array with mongoose

I have an array with multiple objects in it (there can be more than two). Now I need to update an element (change verified to true) inside the object (e.g. an object with method = "app"). If the object doesn't exist yet, it should be recreated. Is there any way to handle this with Mongoose?

enter image description here

I have found a solution for updating, but it does not solve the problem when no object exists

const result = await User.updateOne({email},
    { $set: { "multifactors.$[elem].verified" : true } },
    { arrayFilters: [ { "elem.method": "app" } ] }
)

Upvotes: 0

Views: 58

Answers (1)

Charchit Kapoor
Charchit Kapoor

Reputation: 9284

This is one way of doing it, using a pipelined update.

a. Check if the array contains the required object using $filter and $size.

b. If it's there, updates the matching object $map.

c. Else, append the new object to the array.

db.collection.update({},
[
  {
    "$set": {
      "multifactors": {
        $cond: {
          if: {
            $gt: [
              {
                $size: {
                  $filter: {
                    input: "$multifactors",
                    as: "factor",
                    cond: {
                      $eq: [
                        "$$factor.method",
                        "app"
                      ]
                    }
                  }
                }
              },
              0
            ]
          },
          then: {
            $map: {
              input: "$multifactors",
              as: "factor",
              in: {
                $cond: {
                  if: {
                    $eq: [
                      "$$factor.method",
                      "app"
                    ]
                  },
                  then: {
                    $mergeObjects: [
                      "$$factor",
                      {
                        verified: true
                      }
                    ]
                  },
                  else: "$$factor"
                }
              }
            }
          },
          else: {
            $concatArrays: [
              "$multifactors",
              [
                {
                  method: "app",
                  verified: true
                }
              ]
            ]
          }
        }
      }
    }
  }
])

Playground link.

Upvotes: 1

Related Questions