Comment renommer un champ pour tous les documents dans MongoDB?


223

En supposant 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 "supplémentaire" en "dernier" dans tous les documents? J'ai vu l' opérateur $ rename dans la documentation mais je ne sais pas vraiment comment spécifier un sous-champ.

Réponses:


423

Vous pouvez utiliser:

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

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

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

Le false, truedessus dans le procédé sont les suivants : { upsert:false, multi:true }. Vous devez multi:truemettre à jour tous vos enregistrements.

Ou vous pouvez utiliser l'ancienne 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

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

La syntaxe générale de ceci est

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

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


52
Juste un mot pour si vous cogner la tête contre le mur parce que rien est mis à jour en masse: la false, truedans la updateméthode de la $renameversion sont: { upsert:false, multi:true }. Vous devez multi:truemettre à jour tous vos enregistrements.
RickyA

1
et si j'obtiens, il upsert:truecréera un nom de champ si le nom de champ n'existe pas, par défaut à false.
IGRACH

1
Pour une raison quelconque, cela n'a pas fonctionné pour moi lorsque j'ai utilisé la "table.field" : "table.field"syntaxe. Cela a fonctionné lorsque je viens d'utiliser la "field" : "field"syntaxe.
Ben

@Steve name.lastne l'est pas table.field. Si vous lisez la question, vous pouvez voir que le namechamp contient un objet.
Marc Dingena

Cela fonctionne-t-il également avec les tableaux? Puis-je faire db.foo.update({}, {$rename:{"name.0.additional":"name.0.last"}}, false, true):?
bncc

49

s'il vous plaît essayez db.collectionName.update({}, { $rename : { 'name.additional' : 'name.last' } }, { multi: true } )

et lisez ceci :) http://docs.mongodb.org/manual/reference/operator/rename/#_S_rename


1
Veuillez mettre à jour le lien, la nouvelle documentation ne dit rien sur les options upsertet multi.
Akos K

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

15

Si jamais vous devez faire la même chose avec mongoid:

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

METTRE À JOUR

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

Model.all.rename(old_field: :new_field)

11
Il y a un changement de syntaxe dans le dernier monogoïde (4.0.0)Model.all.rename(old_field: :new_field)
Calin

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

2

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


0

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

Cela 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!");
}

0

J'utilise Mongo 3.4.0

L'opérateur $ rename met à jour le nom d'un champ et a la forme suivante:

{$rename: { <field1>: <newName1>, <field2>: <newName2>, ... } }

par exemple

db.getCollection('user').update( { _id: 1 }, { $rename: { 'fname': 'FirstName', 'lname': 'LastName' } } )

Le nouveau nom de champ doit être différent du nom de champ existant. Pour spécifier un dans un document incorporé, utilisez la notation par points.

Cette opération renomme le champ nmae à nommer pour tous les documents de la collection:

db.getCollection('user').updateMany( {}, { $rename: { "add": "Address" } } )

db.getCollection('user').update({}, {$rename:{"name.first":"name.FirstName"}}, false, true);

Dans la méthode ci-dessus false, true sont: {upsert: false, multi: true}. Pour mettre à jour tous vos enregistrements, vous avez besoin du multi: true.

Renommer un champ dans un document incorporé

db.getCollection('user').update( { _id: 1 }, { $rename: { "name.first": "name.fname" } } )

utilisez le lien: https://docs.mongodb.com/manual/reference/operator/update/rename/


L'option d'intégration ne fonctionne pas ... Je reçois cette erreur "ne peut pas utiliser la partie (adresse de address.city) pour traverser l'élément"
Huzaifa Saifuddin

0

Si vous utilisez MongoMapper, cela fonctionne:

Access.collection.update( {}, { '$rename' => { 'location' => 'location_info' } }, :multi => true )
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.