arraysmongodb

MongoDB $unset with all positional operator $[] only if array field exists


I'm trying to use the $[] (positional array-wide update operator) to $unset a field from all nested documents in an array.

Imagine a document like this:

{
  "_id": 123,
  "orderDate": "2025-01-01T12:34:56Z",
  "items": [
    {
      "name": "Fork",
      "shipDate": "2025-01-01T12:34:56Z",
      "shipQuantity": 6
    },
    {
      "name": "Spoon",
      "shipDate": "2025-01-01T12:34:56Z"
    },
    {
      "name": "Knife"
    }
  ]
}

I can remove orderDate and each items.shipDate and items.shipQuantity like this:

db.x.update({ _id: 123 }, { $unset: { orderDate: 1, "items.$[].shipDate": 1, "items.$[].shipQuantity": 1 } })

It works regardless of whether each item has the shipDate and shipQuantity fields. However, if items array doesn't exist, I get this error: MongoServerError: The path 'items' must exist in the document in order to apply array updates.

Why is this even an error? I'm trying to remove something that already doesn't exist. It should just silently ignore the operation on that field instead of failing the entire query. Assuming I'm updating multiple fields like this and don't know in advance whether items will exist in the document, how do I work around this problematic behavior?


Solution

  • For a quick workaround, you can use $unset in an update with aggregation pipeline.

    db.collection.update({},
    [
      {
        $unset: [
          "orderDate",
          "items.shipDate",
          "items.shipQuantity"
        ]
      }
    ])
    

    Mongo Playground