Bagaimana Anda mengganti nama basis data MongoDB?

484

Ada kesalahan ketik pada nama database MongoDB saya dan saya ingin mengganti nama database.

Saya dapat menyalin dan menghapus seperti itu ...

db.copyDatabase('old_name', 'new_name');
use old_name
db.dropDatabase();

Apakah ada perintah untuk mengganti nama database?

Brian Hempel
sumber
dari mongo 4.2 bahkan copyDatabasesudah ditinggalkan
Sumit Ramteke

Jawaban:

208

Tidak ada. Lihat https://jira.mongodb.org/browse/SERVER-701

Sayangnya, ini bukan fitur sederhana untuk kami terapkan karena cara penyimpanan metadata database di mesin penyimpanan asli (default). Dalam file MMAPv1, namespace (mis: dbName.collection) yang menjelaskan setiap koleksi dan indeks menyertakan nama database, jadi untuk mengganti nama set file database, setiap string namespace tunggal harus ditulis ulang. Dampak ini:

  • file .ns
  • setiap file bernomor tunggal untuk koleksi
  • namespace untuk setiap indeks
  • nama unik internal setiap koleksi dan indeks
  • isi system.namespaces dan system.indexes (atau padanannya di masa depan)
  • lokasi lain saya mungkin hilang

Ini hanya untuk mencapai penggantian nama dari satu basis data dalam contoh mongod mandiri . Untuk set replika di atas perlu dilakukan pada setiap node replika, ditambah pada setiap node setiap entri oplog yang merujuk database ini harus entah bagaimana tidak valid atau ditulis ulang, dan kemudian jika itu adalah cluster berjenggot, kita juga perlu menambahkan ini perubahan ke setiap beling jika DB beling, ditambah server konfigurasi memiliki semua metadata beling dalam hal ruang nama dengan nama lengkapnya.

Sama sekali tidak ada cara untuk melakukan ini pada sistem live.

Untuk melakukannya secara offline, perlu menulis ulang setiap file database tunggal untuk mengakomodasi nama baru, dan pada saat itu akan menjadi lambat seperti perintah "copydb" saat ini ...

pingw33n
sumber
4
Tiket itu telah terbuka untuk waktu yang sangat lama. Saya telah menambahkan suara saya yang kurang penting ke daftar yang sudah lama.
DJ van Wyk
4
Cara mereka membangun DB dan menjelaskannya, mengganti nama tampaknya mustahil - mungkin memerlukan arsitektur yang sama sekali baru. Tampak seperti pengawasan besar tetapi semua adil dalam cinta, perang dan pengembangan perangkat lunak.
serraosays
Jadi MongoDB harus memiliki satu perintah yang memanggil dua fungsi, salin dan lepas? Saya tidak melihat alasan besar untuk memiliki perintah tunggal ini. Tapi itu bisa menyenangkan bagi sebagian orang.
TamusJRoyce
Ketika Anda memberi nama database untuk memulai, HARUS hanya menjadi alias untuk nama internal yang dihasilkan Mongo (menggunakan konvensi penamaan unik secara global). Dengan cara ini, mengubah nama database sesederhana mengubah alias itu dan menyebarkannya ke semua node di cluster. Saya katakan HARUS. Ini bukan kasusnya.
Lonnie Best
396

Anda bisa melakukan ini:

db.copyDatabase("db_to_rename","db_renamed","localhost")
use db_to_rename
db.dropDatabase();

Catatan Editorial: ini adalah pendekatan yang sama yang digunakan dalam pertanyaan itu sendiri tetapi telah terbukti bermanfaat bagi orang lain.

bzmw
sumber
38
Argumen ke-3 sebenarnya bisa dihilangkan, dan itu akan default ke server yang sama.
Haakon
15
Perhatikan bahwa ini tidak berfungsi ketika db_to_rename dan db_renamed hanya berbeda dalam hal. Anda harus menggunakan database sementara dalam situasi itu. (Saya baru saja membahas ini :)
Sebastiaan M
71
Apa bedanya dengan solusi yang disediakan OP?
Salvador Dali
5
ini sama dengan Pertanyaan aktual dengan satu-satunya perbedaan adalah argumen ketiga di copyDatabase metode
Gurbakhshish Singh
2
ini sama dengan Pertanyaan aktual dengan satu-satunya perbedaan adalah argumen ketiga dalam copyDatabasemetode *, yang tidak perlu, dan karena itu solusi yang lebih buruk daripada yang sudah diketahui OP. * cc @GurbakhshishSingh
Trindaz
164

Solusi alternatif: Anda dapat membuang db dan memulihkannya dengan nama yang berbeda. Seperti yang saya alami, ini jauh lebih cepat daripada db.copyDatabase().

$ mongodump -d old_db_name -o mongodump/
$ mongorestore -d new_db_name mongodump/old_db_name

http://docs.mongodb.org/manual/tutorial/backup-with-mongodump/

Tomako
sumber
6
Ini lebih cepat dan sebagai "efek samping", basis data Anda juga dipadatkan.
Comtaler
Ini bagus! Saya sudah punya mongodumpciptaan. Tidak tahu Anda dapat mengembalikannya dengan nama yang berbeda. Terima kasih!
Dushyant Bangal
5
CATATAN: Ini tidak berfungsi jika Anda menggunakan --gzipdan membuat arsip
Dushyant Bangal
9
Ini adalah cara yang disarankan sekarang, karena db.copyDatabase()sekarang sudah tidak digunakan lagi
osolmaz
Memperhatikan tidak, argumen --db( -d) itu sendiri juga tidak digunakan lagi. Sudah ada sedikit pesta penghinaan yang terjadi, tampaknya, diberikan copyDatabasejuga hilang. Saya telah menyodok SERVER-701 dengan catatan saya .
amcgregor
28

CATATAN: Semoga ini berubah dalam versi terbaru.

Anda tidak bisa menyalin data antara instance MongoDB 4.0 mongod (terlepas dari nilai FCV) dan MongoDB 3.4 dan instance mongod sebelumnya. https://docs.mongodb.com/v4.0/reference/method/db.copyDatabase/

PERINGATAN : Hai, orang-orang hanya berhati-hati saat menyalin database, jika Anda tidak ingin mengacaukan koleksi yang berbeda dalam satu database.

Berikut ini menunjukkan kepada Anda cara mengubah nama

> show dbs;
testing
games
movies

Untuk mengganti nama Anda menggunakan sintaks berikut

db.copyDatabase("old db name","new db name")

Contoh:

db.copyDatabase('testing','newTesting')

Sekarang Anda dapat menghapus db lama dengan aman dengan cara berikut

use testing;

db.dropDatabase(); //Here the db **testing** is deleted successfully

Sekarang pikirkan apa yang terjadi jika Anda mencoba mengganti nama database baru dengan nama database yang ada

Contoh:

db.copyDatabase('testing','movies'); 

Jadi dalam konteks ini semua koleksi (tabel) pengujian akan disalin ke basis data film .

Channaveer Hakari
sumber
1
copyDatabasehilang. Saya telah menyodok SERVER-701 dengan catatan saya .
amcgregor
@amcgregor terima kasih telah memberi tahu. Saya telah menambahkan komentar untuk hal yang sama. Semoga ini bisa membantu seseorang.
Channaveer Hakari
8

Meskipun Mongodb tidak menyediakan perintah mengubah nama Database, ia menyediakan perintah r ename Collection , yang tidak hanya mengubah nama koleksi, tetapi juga memodifikasi nama database.

db.adminCommand({renameCollection: "db1.test1", to: "db2.test2"})

Perintah ini hanya memodifikasi metadata, biayanya sangat kecil, kita hanya perlu melintasi semua koleksi di bawahnya db1, diganti namanya db2untuk mencapai penggantian nama nama Database.
Anda dapat melakukannya dalam skrip Js ini

var source = "source";
var dest = "dest";
var colls = db.getSiblingDB(source).getCollectionNames();
for (var i = 0; i < colls.length; i++) {
var from = source + "." + colls[i];
var to = dest + "." + colls[i];
db.adminCommand({renameCollection: from, to: to});
}
HbnKing
sumber
bagaimana dengan indeks dan metadata lain yang dipertahankan atau hilang?
Udit Bhardwaj
@UDB Sangat mungkin dipertahankan. "Mengganti nama koleksi" adalah transformasi namespace , pada dasarnya koleksi Anda bernama foodalam bardatabase memiliki namespace bar.foo. Indeks pada _iddemikian memiliki namespace bar.foo._id_. Mengganti nama koleksi (harus) melakukan pencarian awalan dan mengganti semua ruang nama yang disadarinya, mirip dengan --nsFromdan --nsTo opsi untukmongorestore .
amcgregor
1
Biayanya bisa BESAR! docs.mongodb.com/manual/reference/command/renameCollection/… Jika database target sama dengan database sumber, renameCollection cukup mengubah namespace. Ini adalah operasi cepat. Jika database target berbeda dari database sumber, renameCollection menyalin semua dokumen dari kumpulan sumber ke koleksi target. Tergantung pada ukuran koleksi, ini mungkin membutuhkan waktu lebih lama untuk selesai.
nagylzs
Silakan ubah jawaban Anda. Jawaban Anda sangat membantu, karena dimungkinkan untuk memindahkan koleksi ke database lain dengan perintah ini. Tapi itu tidak benar, dan itu bisa menyesatkan orang lain.
nagylzs
6

Proses di atas lambat, Anda dapat menggunakan metode di bawah ini tetapi Anda harus memindahkan koleksi dengan koleksi ke db lain.

use admin
db.runCommand({renameCollection: "[db_old_name].[collection_name]", to: "[db_new_name].[collection_name]"})
ram madan
sumber
IMHO saran yang sangat baik. Namun, perlu dicatat bahwa ini tidak akan membebaskan ruang dari DB asli tetapi mengubah nama harus jauh lebih cepat daripada menyalin data.
sirfz
1
Gosok itu, ia memang melakukan penyalinan (karena itu tidak menghilangkan ruang, itu bukan benar-benar mengubah nama sederhana) sehingga tidak ada keuntungan nyata untuk metode ini daripada menyalin dan menjatuhkan.
sirfz
5

Tidak ada mekanisme untuk menamai ulang basis data. Jawaban yang saat ini diterima pada saat penulisan adalah faktual benar dan menawarkan beberapa detail latar belakang yang menarik tentang alasan hulu, tetapi tidak menawarkan saran untuk mereplikasi perilaku. Jawaban lain menunjuk copyDatabase, yang tidak lagi menjadi opsi karena fungsi telah dihapus pada 4.0 . Saya telah memperbarui SERVER-701 dengan catatan dan keraguan saya. 🙃

Perilaku Setara melibatkan mongodumpdan mongorestoresedikit menari:

  1. Ekspor data Anda, catat "ruang nama" yang digunakan. Sebagai contoh, pada salah satu dataset saya, saya memiliki koleksi dengan namespace byzmcbehoomrfjcs9vlj.Analytics- awalan itu ( sebenarnya nama database ) akan diperlukan pada langkah berikutnya.

  2. Impor data, penyediaan, --nsFromdan --nsToargumen Anda. ( Dokumentasi. ) Melanjutkan dengan contoh hipotetis saya (dan sangat tidak dapat dibaca) di atas, untuk mengembalikan ke nama yang lebih masuk akal, saya memohon:

mongorestore --archive=backup.agz --gzip --drop \
    --nsFrom 'byzmcbehoomrfjcs9vlj.*' --nsTo 'rita.*'

Beberapa orang mungkin juga menunjuk --dbargumen ke mongorestore, namun ini juga sudah usang dan memicu peringatan terhadap penggunaan pada cadangan folder non-BSON dengan saran yang sepenuhnya salah untuk " use --nsInclude instead". Terjemahan namespace di atas setara dengan penggunaan --dbopsi, dan merupakan setup manipulasi namespace yang benar untuk digunakan karena kami tidak berusaha menyaring apa yang sedang dipulihkan.

amcgregor
sumber
1
--nsFromdan --nsTobekerja untuk saya. Terima kasih!
Bhargav Shah
mongodump dengan nsFrom / To adalah jawaban resmi pada 2020
PaoloC
4

Saya mencoba melakukannya.

db.copyDatabase('DB_toBeRenamed','Db_newName','host') 

dan mengetahui bahwa itu sudah ditinggalkan oleh komunitas mongo meskipun ia membuat cadangan atau berganti nama menjadi DB.

WARNING: db.copyDatabase is deprecated. See http://dochub.mongodb.org/core/copydb-clone-deprecation
{
        "note" : "Support for the copydb command has been deprecated. See 
        http://dochub.mongodb.org/core/copydb-clone-deprecation",
        "ok" : 1
}

Jadi tidak yakin dengan pendekatan di atas saya harus mengambil Dump lokal menggunakan perintah di bawah ini

mongodump --host --db DB_TobeRenamed --out E://FileName/

terhubung ke Db.

use DB_TobeRenamed

kemudian

db.dropDatabase()

kemudian mengembalikan DB dengan perintah.

mongorestore -host hostName -d Db_NewName E://FileName/
Abhishek kumar
sumber
2

Jika Anda memasukkan semua data Anda ke basis data admin (Anda tidak seharusnya), Anda akan melihat db.copyDatabase()tidak akan berfungsi karena pengguna Anda membutuhkan banyak hak istimewa yang Anda mungkin tidak ingin memberikannya. Berikut ini adalah skrip untuk menyalin basis data secara manual:

use old_db
db.getCollectionNames().forEach(function(collName) {
    db[collName].find().forEach(function(d){
        db.getSiblingDB('new_db')[collName].insert(d); 
    }) 
});
François Guthmann
sumber