問題產(chǎn)生的背景
最近Java組的同事向我請(qǐng)教了一個(gè)問題镰官,就是他們發(fā)現(xiàn)Navicat中對(duì)mysql之類的數(shù)據(jù)庫都有重命名DB名字的功能巫俺,但是針對(duì)mongodb竟然沒有這個(gè)功能采缚,作為強(qiáng)迫癥的開發(fā)者锄贼,不能改名曲稼,絕對(duì)不能忍。
頭腦風(fēng)暴的解決方案
大家提供的想法是通過copydb來實(shí)現(xiàn)硕噩,將數(shù)據(jù)庫的數(shù)據(jù)拷貝到命名好的數(shù)據(jù)庫中假残,然后刪除老的數(shù)據(jù)庫,但是我們現(xiàn)有的DB里數(shù)據(jù)非常多炉擅,執(zhí)行copydb操作太耗時(shí)辉懒,顯示該方法不可取。
峰回路轉(zhuǎn)的解決方案
為了解決這個(gè)問題谍失,仔細(xì)查了一下Mongodb的官方文檔眶俩,
雖然MongoDB沒有renameDatabase的命令,但提供了renameCollection()這個(gè)命令快鱼,詳情參考[官方文檔](https://docs.mongodb.com/manual/reference/method/db.collection.renameCollection/index.html)
這個(gè)命令并不是僅僅能修改collection的名字颠印,同時(shí)也可以修改database。例如我們執(zhí)行如下命令:
```JavaScript
db.adminCommand({renameCollection: "test_db1.test_collection1", to: "test_db2.test_collection2"})
```
上述命令實(shí)現(xiàn)了將test_db1下的test_collection1抹竹,重命名為test_db2下的test_collection2线罕。測(cè)試過程中你會(huì)發(fā)現(xiàn)他會(huì)首先創(chuàng)建一個(gè)目標(biāo)數(shù)據(jù)庫,而且所有的collection都會(huì)出現(xiàn)一個(gè)temp的后綴窃判,過一小會(huì)兒后钞楼,源數(shù)據(jù)庫就消失了。遷移就成功了袄琳。這個(gè)命令只修改元數(shù)據(jù)询件,開銷很小,重命名過程很快就可以完成了唆樊。
有了這個(gè)功能宛琅,要實(shí)現(xiàn)源數(shù)據(jù)庫重命名為目標(biāo)數(shù)據(jù)庫,只需要遍歷源數(shù)據(jù)庫下所有的集合逗旁,重命名到目標(biāo)數(shù)據(jù)庫下嘿辟,就實(shí)現(xiàn)了renameDatabase的功能,我們知道m(xù)ongodb是支持直接執(zhí)行js腳本的,因此直接show you codes:
```JavaScript
collection_list = db.getSiblingDB("original_db_name").getCollectionNames();
for (let i = 0; i< collection_list.length; i++) {
? ? let original_db_name = "original_db_name" +"." + collection_list[i];
? ? let target_db_name = "target_db_name"+"."+ collection_list[i];
? ? db.adminCommand({renameCollection: original_db_name, to: target_db_name});
}
```
總結(jié)
遇到問題红伦,多閱讀官方文檔往往會(huì)得到意想不到的驚喜介陶。