MongoDB: updating an array in an array

It seems I have a problem accessing the contents of an array nested in an array in a mongodb document. I have no problem accessing the first arrays of the "group" with a query like the following ...

db.orgs.update({_id: org_id, "groups._id": group_id} , {$set: {"groups.$.name": "new_name"}}); 

When I run into a problem, I try to change the properties of an element in an array of "functions" nested in an array of "group".

Here is a sample document that looks like

  { "_id" : "v5y8nggzpja5Pa7YS", "name" : "Example", "display_name" : "EX1", "groups" : [ { "_id" : "s86CbNBdqJnQ5NWaB", "name" : "Group1", "display_name" : "G1", "features" : [ { _id : "bNQ5Bs8BWqJn6CdNa" type : "blog", name : "[blog name]" owner_id : "ga5YgvP5yza7pj8nS" }, ] }, ] }, 

And this is the request I was trying to use.

 db.orgs.update({_id: "v5y8nggzpja5Pa7YS", "groups._id": "qBX3KDrtMeJGvZWXZ", "groups.features._id":"bNQ5Bs8BWqJn6CdNa" }, {$set: {"groups.$.features.$.name":"New Blog Name"}}); 

It returns with an error message:

 WriteResult({ "nMatched" : 0, "nUpserted" : 0, "nModified" : 0, "writeError" : { "code" : 2, "errmsg" : "Too many positional (ie '$') elements found in path 'groups.$.features.$.name'" } }) 

It seems that mongo does not support modifying arrays nested in arrays through a positional element?

Is there a way to change this array without taking it all out, modifying it and then reinserting it again? With multiple attachments, how is it, the standard practice of creating a new collection? (Despite the fact that data is needed only when parental data is needed) Should I change the structure of the document so that the second nested array is an object and access to it through the key? (If the key is an integer value that can act as "_id")

 groups.$.features.[KEY].name 

What is considered the β€œright” way to do this?

+6
source share
1 answer

After some more research, it seems that the only way to change the array in the array would be with some external logic to find the index of the element I want to change. This requires that each change has a search query to determine the index, and then an update request to modify the array. This does not seem to be the best way.

Link to the 2010 JIRA case requesting multiple positional elements ...

Since I will always know the identifier of this function, I decided to revise the structure of my document.

  { "_id" : "v5y8nggzpja5Pa7YS", "name" : "Example", "display_name" : "EX1", "groups" : [ { "_id" : "s86CbNBdqJnQ5NWaB", "name" : "Group1", "display_name" : "G1", "features" : { "1" : { type : "blog", name : "[blog name]" owner_id : "ga5YgvP5yza7pj8nS" }, } }, ] }, 

With the new structure, changes can be made as follows:

 db.orgs.update({_id: "v5y8nggzpja5Pa7YS", "groups._id": "s86CbNBdqJnQ5NWaB"}, {$set: {"groups.$.features.1.name":"Blog Test 1"}}); 
+3
source

Source: https://habr.com/ru/post/988931/


All Articles