Mongodb update deeply nested subdocument

mongodb

Solution

Unfortunately, you can't use the `$` operator more than once per key, so you have to use numeric values for the rest. As in:

db.myCollection.update({
    "id": 1, 
    "forecasts.forecast-id": 123, 
    "forecasts.levels.level": "proven", 
    "forecasts.levels.configs.config": "Custom 1"
  },
  {"$set": {"forecasts.$.levels.0.configs.0": newData}}
)

MongoDB's support for updating nested arrays is poor. So you're best off avoiding their use if you need to update the data frequently, and consider using multiple collections instead.

One possibility: make `forecasts` its own collection, and assuming you have a fixed set of `level` values, make `level` an object instead of an array:

{
  _id: 123,
  parentId: 1,
  name: "Forecast 1", 
  levels: {
    proven: { 
      configs: [
        { 
          config: "Custom 1",
          variables: [{ x: 1, y:2, z:3}]
        }, 
        { 
          config: "Custom 2",
          variables: [{ x: 10, y:20, z:30}]
        }, 
      ]
    },
    likely: {
      configs: [
        { 
          config: "Custom 1",
          variables: [{ x: 1, y:2, z:3}]
        }, 
        { 
          config: "Custom 2",
          variables: [{ x: 10, y:20, z:30}]
        }, 
      ]
    }
  }
}

Then you can update it using:

db.myCollection.update({
    _id: 123,
    'levels.proven.configs.config': 'Custom 1'
  },
  { $set: { 'levels.proven.configs.$': newData }}
)

Problem

I have a document structure that is deeply nested, like this: ``` {id: 1, forecasts: [ { forecast_id: 123, name: "Forecast 1", levels: [ { level: "proven", configs: [ { config: "Custom 1", variables: [{ x: 1, y:2, z:3}] }, { config: "Custom 2", variables: [{ x: 10, y:20, z:30}] }, ] }, { level: "likely", configs: [ { config: "Custom 1", variables: [{ x: 1, y:2, z:3}] }, { config: "Custom 2", variables: [{ x: 10, y:20, z:30}] }, ] } ] }, ] } ``` I'm trying to update the collection to insert a new config, that looks like this: ``` newdata = { config: "Custom 1", variables: [{ x: 111, y:2222, z:3333}] } ``` I'm trying something like this in mongo (in Python): ``` db.myCollection.update({"id": 1, "forecasts.forecast-id": 123, "forecasts.levels.level": "proven", "forecasts.levels.configs.config": "Custom 1" }, {"$set": {"forecasts.$.levels.$.configs.$": newData}} ) ``` I'm getting "Cannot apply the positional operator without a corresponding query field containing an array" error though. What is the proper way to do this in mongo? This is mongo v2.4.1.

Original source