268 votes

Comment puis-je renommer un champ pour tous les documents dans MongoDB ?

Supposons que j'ai une collection dans MongoDB avec 5000 enregistrements, chacun contenant quelque chose de similaire à :

{
"occupation":"Doctor",
"name": {
   "first":"Jimmy",
   "additional":"Smith"
}

Existe-t-il un moyen simple de renommer le champ "additional" en "last" dans tous les documents ? J'ai vu le $rename dans la documentation, mais je ne sais pas vraiment comment spécifier une sous-zone.

491voto

Felix Yan Points 3943

Vous pouvez utiliser :

db.foo.update({}, {$rename:{"name.additional":"name.last"}}, false, true);

Ou simplement mettre à jour les documents qui contiennent la propriété :

db.foo.update({"name.additional": {$exists: true}}, {$rename:{"name.additional":"name.last"}}, false, true);

El false, true dans la méthode ci-dessus sont : { upsert:false, multi:true } . Vous avez besoin de la multi:true de mettre à jour tous vos dossiers.

Ou vous pouvez utiliser la première méthode :

remap = function (x) {
  if (x.additional){
    db.foo.update({_id:x._id}, {$set:{"name.last":x.name.additional}, $unset:{"name.additional":1}});
  }
}

db.foo.find().forEach(remap);

Dans MongoDB 3.2, vous pouvez également utiliser la fonction

db.students.updateMany( {}, { $rename: { "oldname": "newname" } } )

La syntaxe générale est la suivante

db.collection.updateMany(filter, update, options)

https://docs.mongodb.com/manual/reference/method/db.collection.updateMany/

57 votes

Un mot pour ceux qui se tapent la tête contre le mur parce que rien n'est mis à jour en masse : le false, true en el update de la méthode $rename version sont : { upsert:false, multi:true } . Vous avez besoin de la multi:true pour mettre à jour tous vos dossiers.

1 votes

Et si je l'obtiens upsert:true créera le nom du champ si le nom du champ n'existe pas, la valeur par défaut est false .

1 votes

Pour une raison inconnue, cela n'a pas fonctionné pour moi lorsque j'ai utilisé la fonction "table.field" : "table.field" la syntaxe. Cela a fonctionné lorsque j'ai simplement utilisé le "field" : "field" la syntaxe.

58voto

Alex Points 201

Vous pouvez utiliser le $rename opérateur de mise à jour des champs :

db.collection.update(
  {},
  { $rename: { 'name.additional': 'name.last' } },
  { multi: true }
)

2 votes

Selon la nouvelle documentation, cela devrait ressembler à : db.collectionName.updateMany({}, { $rename : { 'name.additional' : 'name.last' } } )

0 votes

@1r3k c'est vieux mais pour aider les autres à éviter la confusion, non, updateMany est une commande Mongoose, pas une commande MongoDB. Cette commande ne fonctionnera pas.

0 votes

@ChumiestBucket non, c'est correct. UpdateMany est une commande mongodb. Voir ici : docs.mongodb.com/manuel/référence/méthode/

15voto

metakungfu Points 820

Si jamais vous avez besoin de faire la même chose avec mongoid :

Model.all.rename(:old_field, :new_field)

UPDATE

Il y a un changement dans la syntaxe dans monogoid 4.0.0 :

Model.all.rename(old_field: :new_field)

11 votes

La syntaxe a été modifiée dans la dernière version de Monogoid (4.0.0). Model.all.rename(old_field: :new_field)

0 votes

Comment puis-je utiliser cette option pour un document intégré ?

4voto

Mahan Points 345

N'importe qui pourrait potentiellement utiliser cette commande pour renommer un champ de la collection (en n'utilisant aucun _id) :

dbName.collectionName.update({}, {$rename:{"oldFieldName":"newFieldName"}}, false, true);

voir FYI

0voto

d1jhoni1b Points 1110

Ce code nodejs fait juste cela, comme @Felix Yan l'a mentionné, l'ancienne méthode semble fonctionner parfaitement, j'ai eu quelques problèmes avec d'autres snipets, j'espère que cela vous aidera.

Ceci renommera la colonne "oldColumnName" en "newColumnName" de la table "documents".

var MongoClient = require('mongodb').MongoClient
  , assert = require('assert');

// Connection URL
//var url = 'mongodb://localhost:27017/myproject';
var url = 'mongodb://myuser:mypwd@myserver.cloud.com:portNumber/databasename';

// Use connect method to connect to the server
MongoClient.connect(url, function(err, db) {
  assert.equal(null, err);
  console.log("Connected successfully to server");

  renameDBColumn(db, function() {
    db.close();
  });

});

//
// This function should be used for renaming a field for all documents
//
var renameDBColumn = function(db, callback) {
  // Get the documents collection
  console.log("renaming database column of table documents");
  //use the former way:
  remap = function (x) {
    if (x.oldColumnName){
      db.collection('documents').update({_id:x._id}, {$set:{"newColumnName":x.oldColumnName}, $unset:{"oldColumnName":1}});
    }
  }

  db.collection('documents').find().forEach(remap);
  console.log("db table documents remap successfully!");
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X