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.
Sharing my lessons learned. I faced the same requirement recently where i need to update a nested array item. My structure is as follows
My requirement is to add some fields in a specific units[]. My solution is first to find the index of the nested array item (say foundUnitIdx) The two techniques I used are
specify the dynamic field in $set using the [] syntax
Hope this helps others. :)
Managed to solve it with using mongoose:
All you need to know is the '_id's of all of the sub-document in the chain (mongoose automatically create '_id' for each sub-document).
for example -
More about the sub-document _id method in mongoose documentation.
explanation:_id is for the SchemaName, _id1 for sub1 and _id2 for sub2 - you can keep chaining like that.
*You don't have to use findById method, but it's seem to me the most convenient as you need to know the rest of the '_id's anyway.
It's fixed. https://jira.mongodb.org/browse/SERVER-831
But this feature is available starting with the MongoDB 3.5.12 development version.
Note: This question asked on
Aug 11 2013
and it's resolved onAug 11 2017
This is a very OLD bug in MongoDB
https://jira.mongodb.org/browse/SERVER-831
Unfortunately, you can't use the
$
operator more than once per key, so you have to use numeric values for the rest. As in: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 oflevel
values, makelevel
an object instead of an array:Then you can update it using:
MongoDB has introduced ArrayFilters to tackle this issue in Version 3.5.2 and later.
[https://docs.mongodb.com/manual/reference/method/db.collection.update/#specify-arrayfilters-for-an-array-update-operations][1]
Let's say the Schema design as follows :
And Document created looks like this :
Say I want to update the "url" of an image. Given -
"document id", "tour_name" and "title"
For this the update query :