Jak mogę zmienić nazwę pola dla wszystkich dokumentów w MongoDB?

223

Zakładając, że mam kolekcję w MongoDB z 5000 rekordami, z których każda zawiera coś podobnego do:

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

Czy istnieje prosty sposób na zmianę nazwy pola „dodatkowe” na „ostatnie” we wszystkich dokumentach? W dokumentacji widziałem operatora zmiany nazwy $ , ale nie bardzo wiem, jak określić podpole.

soulkphp
źródło

Odpowiedzi:

424

Możesz użyć:

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

Lub po prostu zaktualizuj dokumenty zawierające właściwość:

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

false, trueW powyższym sposobie są następujące: { upsert:false, multi:true }. Musisz multi:truezaktualizować wszystkie swoje rekordy.

Lub możesz użyć poprzedniego sposobu:

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

W MongoDB 3.2 możesz także użyć

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

Ogólna składnia tego jest

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

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

Felix Yan
źródło
52
Tylko słowo, jeśli walić głową o ścianę, bo nic nie jest masowa aktualizacja: false, truew updatesposobie $renamewersji: { upsert:false, multi:true }. Musisz multi:truezaktualizować wszystkie swoje rekordy.
RickyA,
1
a jeśli upsert:trueotrzymam to utworzy nazwę pola, jeśli nazwa pola nie istnieje, domyślnie jest to false.
IGRACH
1
Z jakiegoś powodu nie działało to dla mnie, gdy użyłem "table.field" : "table.field"składni. Zadziałało, kiedy właśnie użyłem "field" : "field"składni.
Ben
@ Steve name.lastnie jest table.field. Jeśli przeczytasz pytanie, zobaczysz, że namepole zawiera obiekt.
Marc Dingena
Czy to również działa z tablicami? Mogę zrobić: db.foo.update({}, {$rename:{"name.0.additional":"name.0.last"}}, false, true)?
bncc
49

proszę spróbować db.collectionName.update({}, { $rename : { 'name.additional' : 'name.last' } }, { multi: true } )

i przeczytaj to :) http://docs.mongodb.org/manual/reference/operator/rename/#_S_rename

Alex
źródło
1
Zaktualizuj link, wygląda na to, że nowa dokumentacja nie mówi nic o opcjach upserti multi.
Akos K
1
Zgodnie z nową dokumentacją powinien on wyglądać następująco: db.collectionName.updateMany ({}, {$ rename: {'name.additional': 'name.last'}})
1r3k
15

Jeśli kiedykolwiek musisz zrobić to samo z mongoid:

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

AKTUALIZACJA

Nastąpiła zmiana w składni monogoid 4.0.0:

Model.all.rename(old_field: :new_field)
metakungfu
źródło
11
Nastąpiła zmiana w składni ostatniego monogoidu (4.0.0)Model.all.rename(old_field: :new_field)
Calin
Jak korzystać z tej opcji w przypadku osadzonego dokumentu
Huzaifa Saifuddin
2

Każdy może potencjalnie użyć tego polecenia, aby zmienić nazwę pola z kolekcji (nie używając żadnego _id):

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

patrz FYI

Mants
źródło
0

Ten kod nodejs po prostu to robi, ponieważ jak wspomniał @Felix Yan, poprzedni sposób wydaje się działać dobrze, miałem pewne problemy z innymi fragmentami, mam nadzieję, że to pomoże.

Spowoduje to zmianę nazwy kolumny „oldColumnName” na „newColumnName” tabeli „dokumenty”

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

// Connection URL
//var url = 'mongodb://localhost:27017/myproject';
var url = 'mongodb://myuser:[email protected]: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!");
}
d1jhoni1b
źródło
0

Używam Mongo 3.4.0

Operator $ rename aktualizuje nazwę pola i ma następującą postać:

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

na przykład

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

Nowa nazwa pola musi różnić się od istniejącej nazwy pola. Aby określić w osadzonym dokumencie, użyj notacji kropkowej.

Ta operacja zmienia nazwę pola nmae na nazwę dla wszystkich dokumentów w kolekcji:

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

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

W powyższej metodzie false, true to: {upsert: false, multi: true}. Aby zaktualizować wszystkie rekordy, potrzebujesz multi: true.

Zmień nazwę pola w osadzonym dokumencie

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

użyj linku: https://docs.mongodb.com/manual/reference/operator/update/rename/

Swadeshi
źródło
Opcja osadzania nie działa ... Otrzymuję ten błąd „nie można użyć części (adresu adresu.city) do przejścia elementu”
Huzaifa Saifuddin
0

Jeśli używasz MongoMapper, działa to:

Access.collection.update( {}, { '$rename' => { 'location' => 'location_info' } }, :multi => true )
Jon Kern
źródło