คุณจะเปลี่ยนชื่อฐานข้อมูล MongoDB ได้อย่างไร


483

มีการพิมพ์ผิดในชื่อฐานข้อมูล MongoDB ของฉันและฉันต้องการเปลี่ยนชื่อฐานข้อมูล

ฉันสามารถคัดลอกและลบเช่นนี้ ...

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

มีคำสั่งให้เปลี่ยนชื่อฐานข้อมูลหรือไม่?


จากmongo 4.2ถึงแม้copyDatabaseจะเลิกใช้แล้ว
Sumit Ramteke

คำตอบ:


208

ไม่มีเลย ดูhttps://jira.mongodb.org/browse/SERVER-701

น่าเสียดายที่นี่ไม่ใช่คุณสมบัติที่ง่ายสำหรับเราที่จะใช้งานเนื่องจากวิธีการที่ข้อมูลเมตาของฐานข้อมูลถูกเก็บไว้ในเอ็นจิ้นการจัดเก็บ (เริ่มต้น) ดั้งเดิม ในไฟล์ MMAPv1 เนมสเปซ (เช่น: dbName.collection) ที่อธิบายการรวบรวมและดัชนีทุกรายการจะมีชื่อฐานข้อมูลดังนั้นหากต้องการเปลี่ยนชื่อชุดของไฟล์ฐานข้อมูลสตริงเนมสเปซเดียวทั้งหมดจะต้องถูกเขียนใหม่ ผลกระทบนี้:

  • ไฟล์. ns
  • ทุกไฟล์หมายเลขเดียวสำหรับคอลเลกชัน
  • namespace สำหรับทุกดัชนี
  • ชื่อเฉพาะภายในของแต่ละการรวบรวมและดัชนี
  • เนื้อหาของ system.namespaces และ system.indexes (หรือรายการเทียบเท่าในอนาคต)
  • ที่อื่น ๆ ที่ฉันอาจหายไป

นี่เป็นเพียงการเปลี่ยนชื่อฐานข้อมูลเดียวในอินสแตนซ์ Mongo แบบสแตนด์อโลน สำหรับชุดเรพลิกาข้างต้นจะต้องทำในทุกโหนดเรพลิกาบวกกับแต่ละโหนดทุกรายการ oplog เดียวที่อ้างถึงฐานข้อมูลนี้จะต้องมีการตรวจสอบหรือเขียนใหม่อย่างใดอย่างหนึ่งและถ้ามันเป็นกระจุกคลัสเตอร์หนึ่งก็ต้องเพิ่มสิ่งเหล่านี้ เปลี่ยนเป็นทุกชิ้นส่วนถ้าฐานข้อมูลถูกลบรวมทั้งเซิร์ฟเวอร์การกำหนดค่าจะมีข้อมูลเมตาทั้งหมดในส่วนของเนมสเปซที่มีชื่อเต็ม

จะไม่มีทางทำสิ่งนี้บนระบบจริง

หากต้องการออฟไลน์มันจะต้องเขียนไฟล์ฐานข้อมูลใหม่ทุกไฟล์เพื่อรองรับชื่อใหม่และ ณ จุดนั้นมันจะช้าเท่ากับคำสั่ง "copydb" ปัจจุบัน ...


4
ตั๋วดังกล่าวเปิดให้บริการมาเป็นเวลานาน ฉันได้เพิ่มคะแนนโหวตที่ไม่สำคัญไปยังรายการที่มีความยาวแล้ว
DJ van Wyk

4
วิธีที่พวกเขาสร้างฐานข้อมูลและอธิบายการเปลี่ยนชื่อดูเหมือนเป็นไปไม่ได้ - อาจต้องใช้สถาปัตยกรรมใหม่ทั้งหมด ดูเหมือนว่าจะมีการกำกับดูแลที่ยิ่งใหญ่ แต่ทุกคนก็มีความยุติธรรมในด้านความรักสงครามและการพัฒนาซอฟต์แวร์
serraosays

ดังนั้น MongoDB ควรมีคำสั่งเดียวที่เรียกใช้สองฟังก์ชันคัดลอกและวาง ฉันไม่เห็นเหตุผลใหญ่ที่จะมีคำสั่งเดียวนี้ แต่มันก็ดีสำหรับบางคน
TamusJRoyce

เมื่อคุณตั้งชื่อฐานข้อมูลที่จะเริ่มต้นนั่นควรเป็นเพียงนามแฝงสำหรับชื่อภายในที่ Mongo สร้างขึ้น (โดยใช้หลักการตั้งชื่อที่ไม่ซ้ำกันทั่วโลก) ด้วยวิธีนี้การเปลี่ยนชื่อของฐานข้อมูลนั้นง่ายพอ ๆ กับการเปลี่ยนนามแฝงนั้นและเผยแพร่ไปยังโหนดทั้งหมดในคลัสเตอร์ ฉันบอกว่าควร กรณีนี้ไม่ได้.
Lonnie Best

396

คุณสามารถทำได้:

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

หมายเหตุบรรณาธิการ: นี่เป็นวิธีการเดียวกับที่ใช้ในคำถาม แต่ได้พิสูจน์แล้วว่ามีประโยชน์ต่อผู้อื่นโดยไม่คำนึงถึง


38
อาร์กิวเมนต์ที่ 3 สามารถละเว้นได้จริงและจะเริ่มต้นไปที่เซิร์ฟเวอร์เดียวกัน
ฮาก

15
โปรดทราบว่าสิ่งนี้ไม่ทำงานเมื่อ db_to_rename และ db_renamed แตกต่างกันในกรณีที่ คุณต้องใช้ฐานข้อมูลชั่วคราวในสถานการณ์นั้น (ฉันเพียงแค่วิ่งเข้าไปในนี้ :)
Sebastiaan M

71
สิ่งนี้แตกต่างจากโซลูชันของ OP หรือไม่?
Salvador Dali

5
สิ่งนี้เหมือนกับคำถามจริงที่มีความแตกต่างเพียงอย่างเดียวคืออาร์กิวเมนต์ที่สามในcopyDatabaseวิธีการ
Gurbakhshish Singh เมื่อ

2
คำถามนี้เหมือนกับคำถามจริงที่มีความแตกต่างเพียงอย่างเดียวคือข้อโต้แย้งที่สามในcopyDatabaseวิธี * ซึ่งไม่จำเป็นดังนั้นจึงเป็นคำตอบที่แย่ยิ่งกว่าที่ OP ทราบแล้ว * cc @GurbakhshishSingh
Trindaz

164

โซลูชันทางเลือก: คุณสามารถดัมพ์ db ของคุณและเรียกคืนในชื่ออื่น ในขณะที่ฉันมีประสบการณ์มันเร็วกว่า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/


6
นี่คือเร็วขึ้นและเป็น "ผลข้างเคียง" ฐานข้อมูลของคุณจะถูกกระชับเช่นกัน
Comtaler

มันเยี่ยมมาก! ฉันได้mongodumpสร้างแล้ว ไม่ทราบว่าคุณสามารถกู้คืนได้ด้วยชื่ออื่น ขอบคุณ!
Dushyant Bangal

5
หมายเหตุ: วิธีนี้ใช้ไม่ได้หากคุณใช้--gzipและสร้างไฟล์เก็บถาวร
Dushyant Bangal

9
นี่เป็นวิธีที่แนะนำตอนนี้เนื่องจากdb.copyDatabase()เลิกใช้แล้ว
osolmaz

เมื่อสังเกตว่าไม่มีอาร์กิวเมนต์--db( -d) อาร์กิวเมนต์ก็ไม่รองรับเช่นกัน ดูเหมือนจะมีปาร์ตี้ที่คัดค้านอยู่copyDatabaseบ้าง ผมเคยแหย่SERVER-701 กับบันทึกของฉัน
amcgregor

28

หมายเหตุ: หวังว่าการเปลี่ยนแปลงนี้จะเป็นเวอร์ชั่นล่าสุด

คุณไม่สามารถคัดลอกข้อมูลระหว่าง MongoDB อินสแตนซ์ MongoDB 4.0 (ไม่ว่าจะเป็นค่า FCV) และ MongoDB 3.4 และอินสแตนซ์ MongoDB รุ่นก่อนหน้า https://docs.mongodb.com/v4.0/reference/method/db.copyDatabase/

ALERT : สวัสดีทุกคนระวังในขณะที่คัดลอกฐานข้อมูลถ้าคุณไม่ต้องการทำให้ชุดสะสมต่าง ๆ แตกต่างกันในฐานข้อมูลเดียว

ต่อไปนี้แสดงวิธีการเปลี่ยนชื่อ

> show dbs;
testing
games
movies

ในการเปลี่ยนชื่อคุณใช้ไวยากรณ์ต่อไปนี้

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

ตัวอย่าง:

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

ตอนนี้คุณสามารถลบฐานข้อมูลเก่าด้วยวิธีต่อไปนี้อย่างปลอดภัย

use testing;

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

ตอนนี้คิดว่าจะเกิดอะไรขึ้นถ้าคุณลองเปลี่ยนชื่อฐานข้อมูลใหม่ด้วยชื่อฐานข้อมูลที่มีอยู่

ตัวอย่าง:

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

ดังนั้นในบริบทนี้ชุดทดสอบทั้งหมด (ตาราง) ของการทดสอบจะถูกคัดลอกไปยังฐานข้อมูลภาพยนตร์


1
copyDatabaseหายไป ผมเคยแหย่SERVER-701 กับบันทึกของฉัน
amcgregor

@amcgregor ขอบคุณที่แจ้งให้ทราบ ฉันได้เพิ่มความคิดเห็นสำหรับเดียวกัน หวังว่ามันจะช่วยได้บ้าง
Channaveer Hakari

8

แม้ว่า Mongodb ไม่ได้จัดเตรียมคำสั่งเปลี่ยนชื่อฐานข้อมูล แต่จะมีคำสั่ง r ename Collectionซึ่งไม่เพียง แต่แก้ไขชื่อคอลเลกชันเท่านั้น แต่ยังแก้ไขชื่อฐานข้อมูลด้วย

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

คำสั่งนี้จะแก้ไขข้อมูลเมตาเท่านั้นค่าใช้จ่ายมีขนาดเล็กมากเราเพียงต้องการสำรวจคอลเลกชันทั้งหมดภายใต้db1เปลี่ยนชื่อเป็นdb2ชื่อฐานข้อมูลเพื่อให้บรรลุ
คุณสามารถทำได้ในสคริปต์ Js นี้

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

สิ่งที่เกี่ยวกับดัชนีและข้อมูลเมตาอื่น ๆ ที่พวกเขารักษาหรือหายไป?
Udit Bhardwaj

@UDB น่าจะรักษาไว้มาก "การเปลี่ยนชื่อคอลเลกชัน" คือการเปลี่ยนแปลง namespaceหลักคอลเลกชันของคุณชื่อfooในbarฐานข้อมูลมี namespace bar.fooของ ดัชนีบน_idจึงมีการ bar.foo._id_namespace การเปลี่ยนชื่อคอลเลกชัน (ควร) ดำเนินการค้นหาคำนำหน้าและแทนที่ใน namespaces ทั้งหมดจะตระหนักถึงความคล้ายคลึงกับ--nsFromและตัวเลือกในการ--nsTo mongorestore
รวบรวม

1
ค่าใช้จ่ายสามารถมากมาย! docs.mongodb.com/manual/reference/command/renameCollection/…หากฐานข้อมูลเป้าหมายเหมือนกับฐานข้อมูลต้นทาง renameCollection จะเปลี่ยนเนมสเปซเพียงอย่างเดียว นี่คือการดำเนินการอย่างรวดเร็ว หากฐานข้อมูลเป้าหมายแตกต่างจากฐานข้อมูลต้นทาง renameCollection จะคัดลอกเอกสารทั้งหมดจากแหล่งรวบรวมไปยังกลุ่มเป้าหมาย ขึ้นอยู่กับขนาดของคอลเลกชันซึ่งอาจใช้เวลานานกว่าจะเสร็จสมบูรณ์
nagylzs

โปรดเปลี่ยนคำตอบของคุณ คำตอบของคุณมีประโยชน์เพราะเป็นไปได้ที่จะย้ายคอลเล็กชันไปยังฐานข้อมูลอื่นด้วยคำสั่งนี้ แต่มันไม่ถูกต้องและสามารถชี้นำผู้อื่นได้
nagylzs

6

กระบวนการข้างต้นช้าคุณสามารถใช้วิธีการด้านล่าง แต่คุณต้องย้ายคอลเล็กชันโดยการรวบรวมไปยังฐานข้อมูลอื่น

use admin
db.runCommand({renameCollection: "[db_old_name].[collection_name]", to: "[db_new_name].[collection_name]"})

ข้อเสนอแนะที่ยอดเยี่ยม IMHO อย่างไรก็ตามมันน่าสังเกตว่าสิ่งนี้จะไม่เพิ่มพื้นที่ว่างจากฐานข้อมูลต้นฉบับ แต่การเปลี่ยนชื่อควรเร็วกว่าการคัดลอกข้อมูล
sirfz

1
เกาว่ามันจะทำสำเนาอยู่ดี (เนื่องจากมันไม่ได้ลบพื้นที่มันไม่ใช่การเปลี่ยนชื่อแบบง่าย ๆ ) ดังนั้นจึงไม่มีข้อได้เปรียบที่แท้จริงสำหรับวิธีนี้ในการคัดลอกและวาง
sirfz

5

ไม่มีกลไกในการตั้งชื่อฐานข้อมูลใหม่ คำตอบที่ได้รับการยอมรับในปัจจุบันในขณะที่เขียนถูกต้องเป็นจริงและข้อเสนอบางรายละเอียดพื้นหลังที่น่าสนใจเช่นการทวนข้อแก้ตัว แต่ข้อเสนอไม่มีข้อเสนอแนะสำหรับการจำลองพฤติกรรม คำตอบอื่น ๆ ชี้ไปที่copyDatabaseซึ่งไม่มีตัวเลือกในฐานะที่เป็นฟังก์ชั่นที่ได้รับการถอดออกใน 4.0 ฉันได้อัปเดตSERVER-701 ด้วยบันทึกและความเหลือเชื่อของฉัน 🙃

พฤติกรรมที่เท่าเทียมกันเกี่ยวข้องกับmongodumpและmongorestoreในการเต้นรำ:

  1. ส่งออกข้อมูลของคุณจดบันทึก "namespaces" ที่ใช้งานอยู่ ตัวอย่างเช่นในหนึ่งในชุดข้อมูลของฉันฉันมีคอลเลกชันที่มี namespace byzmcbehoomrfjcs9vlj.Analytics- คำนำหน้านั้น ( จริง ๆ แล้วชื่อฐานข้อมูล ) จะต้องใช้ในขั้นตอนต่อไป

  2. นำเข้าข้อมูลการจัดหา--nsFromและ--nsToข้อโต้แย้ง ( เอกสาร ) ต่อด้วยตัวอย่างสมมุติ (และอ่านไม่ได้มาก) ของฉันข้างต้นเพื่อเรียกคืนชื่อที่มีความรู้สึกมากขึ้นฉันเรียกใช้:

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

บางคนอาจชี้ไปที่--dbอาร์กิวเมนต์เพื่อ mongorestore อย่างไรก็ตามสิ่งนี้ก็ถูกคัดค้านและทำให้เกิดคำเตือนต่อการใช้งานในการสำรองข้อมูลโฟลเดอร์ที่ไม่ใช่ BSON พร้อมกับคำแนะนำที่ผิดพลาดทั้งหมด " use --nsInclude instead" การแปลเนมสเปซข้างต้นเทียบเท่ากับการใช้--dbตัวเลือกและเป็นการตั้งค่าการจัดการเนมสเปซที่ถูกต้องเพื่อใช้เนื่องจากเราไม่ได้พยายามกรองสิ่งที่ถูกเรียกคืน


1
--nsFromและ--nsToทำงานให้ฉัน ขอบคุณ!
Bhargav Shah

mongodump กับ nsFrom / To เป็นคำตอบอย่างเป็นทางการตั้งแต่ปี 2020
PaoloC

4

ฉันพยายามทำ

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

และรู้ว่ามันได้ถูกคัดค้านโดยชุมชน mongo แม้ว่ามันจะสร้างการสำรองข้อมูลหรือเปลี่ยนชื่อฐานข้อมูล

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
}

ดังนั้นไม่มั่นใจกับวิธีการข้างต้นฉันต้องใช้การถ่ายโอนข้อมูลท้องถิ่นโดยใช้คำสั่งด้านล่าง

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

เชื่อมต่อกับ Db

use DB_TobeRenamed

แล้วก็

db.dropDatabase()

จากนั้นเรียกคืนฐานข้อมูลด้วยคำสั่ง

mongorestore -host hostName -d Db_NewName E://FileName/

2

ในกรณีที่คุณใส่ข้อมูลทั้งหมดของคุณลงในฐานข้อมูลผู้ดูแลระบบ (คุณไม่ควรทำ) คุณจะสังเกตเห็นว่าใช้db.copyDatabase()งานไม่ได้เพราะผู้ใช้ของคุณต้องการสิทธิพิเศษมากมายที่คุณอาจไม่ต้องการให้ นี่คือสคริปต์เพื่อคัดลอกฐานข้อมูลด้วยตนเอง:

use old_db
db.getCollectionNames().forEach(function(collName) {
    db[collName].find().forEach(function(d){
        db.getSiblingDB('new_db')[collName].insert(d); 
    }) 
});
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.