MongoDB renommer le champ de la base de données dans le tableau

je dois renommer indentifier:

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

j'ai essayé

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

mais il renvoie: $rename source may not be dynamic array.

24
demandé sur Dan Dascalescu 2012-02-03 06:33:15

4 réponses

comme mentionné dans la documentation, il n'y a aucun moyen de renommer directement les champs dans les tableaux avec une seule commande. Votre seule option est d'itérer les documents de votre collection, de les lire et de les mettre à jour avec $unset old/$set new operations.

13
répondu Remon van Vliet 2017-11-02 13:11:58

pour ce que cela vaut, bien que cela semble terrible d'avoir à faire, la solution est en fait assez facile. Cela dépend bien sûr du nombre d'enregistrements que vous avez. Mais voici mon exemple:

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);
});

je répète sur ma collection où le tableau est trouvé et le "mauvais" nom est trouvé. J'itère ensuite sur la sous-collection, fixe la nouvelle valeur, supprime l'ancienne et met à jour l'ensemble du document. C'était relativement indolore. Je n'ai que quelques dizaines de milliers de rangées à fouiller., dont seulement quelques douzaines répondent aux critères.

pourtant, j'espère que cette réponse aidera quelqu'un!

Edit: Added snapshot() à la requête. Voir pourquoi dans les commentaires.

vous devez appliquer snapshot () au curseur avant d'extraire tout document de la base de données. Vous ne pouvez utiliser snapshot() qu'avec des collections non protégées.

37
répondu Eli Gassert 2016-01-19 15:13:29

j'ai eu un problème similaire. Dans ma situation, j'ai trouvé que ce qui suit était beaucoup plus facile:

  1. j'ai exporté la collection en json:
mongoexport --db mydb --collection modules --out modules.json
  1. j'ai fait une recherche et un remplacement sur le json en utilisant mon utilitaire d'édition de texte préféré.

  2. j'ai réimporté le fichier édité, laissant tomber l'ancienne collection le long du chemin:

mongoimport --db mydb --collection modules --drop --file modules.json
14
répondu fraccy 2015-01-20 18:18:29

je voudrais aussi renommer une propriété dans array: et j'ai utilisé thaht

db.getCollection('YourCollectionName').find({}).snapshot().forEach(function(a){
    a.Array1.forEach(function(b){
        b.Array2.forEach(function(c){
            c.NewPropertyName = c.OldPropertyName;
            delete c["OldPropertyName"];                   
        });
    });
    db.getCollection('YourCollectionName').save(a)  
});
0
répondu Cedric Michel 2018-08-22 09:07:01