Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MongoDB rename database field within array

I need to rename indentifier in this:

{ "general" :    { "files" :      { "file" :        [           {  "version" :            {  "software_program" : "MonkeyPlus",                    "indentifier" : "6.0.0"            }          }        ]      }    }  } 

I've tried

db.nrel.component.update(   {},   { $rename: {     "general.files.file.$.version.indentifier" : "general.files.file.$.version.identifier"   } },   false, true ) 

but it returns: $rename source may not be dynamic array.

like image 802
Andrew Samuelsen Avatar asked Feb 03 '12 02:02

Andrew Samuelsen


People also ask

How do I update an array in MongoDB?

You can use the updateOne() or updateMany() methods to add, update, or remove array elements based on the specified criteria. It is recommended to use the updateMany() method to update multiple arrays in a collection.

How use MongoDB $set?

In MongoDB, the $set operator is used to replace the value of a field to the specified value. If the given field does not exist in the document, the $set operator will add the field to the specified value. Our database name is 'myinfo' and our collection name is "employee".


2 Answers

For what it's worth, while it sounds awful to have to do, the solution is actually pretty easy. This of course depends on how many records you have. But here's my example:

db.Setting.find({ 'Value.Tiers.0.AssetsUnderManagement': { $exists: 1 } }).snapshot().forEach(function(item) {         for(i = 0; i != item.Value.Tiers.length; ++i)     {         item.Value.Tiers[i].Aum = item.Value.Tiers[i].AssetsUnderManagement;         delete item.Value.Tiers[i].AssetsUnderManagement;     }          db.Setting.update({_id: item._id}, item); }); 

I iterate over my collection where the array is found and the "wrong" name is found. I then iterate over the sub collection, set the new value, delete the old, and update the whole document. It was relatively painless. Granted I only have a few tens of thousands of rows to search through, of which only a few dozen meet the criteria.

Still, I hope this answer helps someone!

Edit: Added snapshot() to the query. See why in the comments.

You must apply snapshot() to the cursor before retrieving any documents from the database. You can only use snapshot() with unsharded collections.

From MongoDB 3.4, snapshot() function was removed. So if using Mongo 3.4+ ,the example above should remove snapshot() function.

like image 110
Eli Gassert Avatar answered Sep 21 '22 10:09

Eli Gassert


As mentioned in the documentation there is no way to directly rename fields within arrays with a single command. Your only option is to iterate over your collection documents, read them and update each with $unset old/$set new operations.

like image 37
Remon van Vliet Avatar answered Sep 20 '22 10:09

Remon van Vliet