ChatGPT解决这个技术问题 Extra ChatGPT

如何重命名 MongoDB 数据库?

我的 MongoDB 数据库名称中有错字,我正在寻找重命名数据库。

我可以像这样copy并删除...

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

是否有重命名数据库的命令?

mongo 4.2 甚至 copyDatabase 也是 deprecated

m
mcont

你可以这样做,如果你使用 MongoDB < 4.2 (ref):

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

编者注:这与问题本身使用的方法相同,但无论如何都证明对其他人有用。


第三个参数实际上可以省略,它将默认为同一服务器。
请注意,当 db_to_rename 和 db_renamed 只是大小写不同时,这不起作用。在这种情况下,您必须使用临时数据库。 (我刚遇到这个:)
这与 OP 提供的解决方案有何不同?
这与实际问题相同,唯一的区别是 copyDatabase 方法中的第三个参数
除了它几乎是原始问题示例的复制粘贴之外,它在 4.0 之后也是无效且无法使用的,因为它们已完全删除 copyDatabase。参考。 my answer 适用于当前的现代方法。
M
M. Justin

替代解决方案:您可以转储您的数据库并以不同的名称恢复它。根据我的经验,它比 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/

鉴于 MongoDB 4.2 中的 copyDatabase was removed,这是当前用于数据库重命名的官方 recommended approach

“copydb”命令已弃用,请改用以下两个命令: mongodump(备份数据) mongorestore(将数据从 mongodump 恢复到新命名空间)


这更快,并且作为“副作用”,您的数据库也被压缩了。
这很棒!我已经创建了一个 mongodump。不知道你可以用不同的名字恢复它。谢谢!
注意:如果您使用 --gzip 并创建存档,这将不起作用
这是现在推荐的方式,因为现在不推荐使用 db.copyDatabase()
请注意,不,--db (-d) 参数本身也已弃用。鉴于copyDatabase is also gone.我戳了SERVER-701 with my notes,似乎正在进行一些弃用派对。
g
gnat

不,没有。请参阅https://jira.mongodb.org/browse/SERVER-701

不幸的是,由于数据库元数据存储在原始(默认)存储引擎中的方式,这对我们来说不是一个简单的功能。在 MMAPv1 文件中,描述每个集合和索引的命名空间(例如:dbName.collection)包括数据库名称,因此要重命名一组数据库文件,必须重写每个命名空间字符串。这会影响: .ns 文件 集合的每个编号文件 每个索引的命名空间 每个集合的内部唯一名称以及 system.namespaces 和 system.indexes 的索引内容(或将来的等价物) 我可能会丢失的其他位置这只是为了在独立的 mongod 实例中完成单个数据库的重命名。对于副本集,需要在每个副本节点上完成上述操作,并且在每个节点上,引用该数据库的每个 oplog 条目都必须以某种方式无效或重写,然后如果它是一个分片集群,还需要添加这些如果对数据库进行分片,则对每个分片进行更改,此外,配置服务器具有所有分片元数据,包括名称空间及其全名。在实时系统上绝对没有办法做到这一点。要离线进行,需要重写每个数据库文件以适应新名称,此时它会像当前的“copydb”命令一样慢......


那张票已经开了很长时间了。我已将我不太重要的投票添加到已经很长的名单中。
他们构建数据库并对其进行解释的方式,重命名似乎是不可能的——可能需要一个全新的架构。似乎是一个很大的疏忽,但在爱情、战争和软件开发方面都是公平的。
那么MongoDB应该有一个命令调用两个函数,copy和drop?我看不出有这个单一命令的重要理由。但这对某些人来说可能很好。
当您开始命名数据库时,它应该只是 Mongo 生成的内部名称的别名(使用全局唯一的命名约定)。这样,更改数据库名称就像更改别名并将其传播到集群中的所有节点一样简单。我说应该。不是这种情况。
这太离谱了
C
Channaveer Hakari

注意:希望这在最新版本中有所改变。您不能在 MongoDB 4.0 mongod 实例(不管 FCV 值)和 MongoDB 3.4 及更早版本的 mongod 实例之间复制数据。 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'); 

因此,在这种情况下,所有测试集合(表)都将被复制到电影数据库中。


@amcgregor 感谢您的通知。我已经添加了相同的评论。希望它对某人有所帮助。
db.copyDatabase 不再在 mongodb 4.4 上
@datinhquoc 是的,将其添加为评论
R
Ravexina

从 4.2 版开始,不推荐使用 copyDatabase。从现在开始,我们应该使用:mongodumpmongorestore

假设我们有一个名为 old_name 的数据库,我们想将其重命名为 new_name

首先我们必须转储数据库:

mongodump --archive="old_name_dump.db" --db=old_name

如果您必须以用户身份进行身份验证,请使用:

mongodump -u username --authenticationDatabase admin \
          --archive="old_name_dump.db" --db=old_name

现在我们将数据库转储为名为 old_name_dump.db 的文件。

要使用新名称恢复:

mongorestore --archive="old_name_dump.db" --nsFrom="old_name.*" --nsTo="new_name.*"

同样,如果您需要进行身份验证,请将此参数添加到命令中:

-u username --authenticationDatabase admin 

参考:https://docs.mongodb.com/manual/release-notes/4.2-compatibility/#remove-support-for-the-copydb-and-clone-commands


您可以使用标准输出作为管道 mongodump --archive --db=old_name | mongorestore --archive --nsFrom='old_name.*' --nsTo='new_name.*' 进行重命名,而不是使用存档文件
t
turivishal

Mongodb虽然没有提供rename Database命令,但是提供了rename Collection command,不仅修改了集合名,还修改了数据库名。

{ renameCollection: "<source_namespace>", to: "<target_namespace>", dropTarget: <true|false>  writeConcern: <document> }
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});
}

使用此命令时要小心

renameCollection 具有不同的性能影响,具体取决于目标命名空间。如果目标数据库与源数据库相同,renameCollection 只是更改命名空间。这是一个快速操作。如果目标数据库与源数据库不同,renameCollection 会将源集合中的所有文档复制到目标集合。根据集合的大小,这可能需要更长的时间才能完成。


索引和其他元数据是维护还是丢失?
@UDB 很可能保留。 “重命名集合”是一种命名空间转换,本质上,您在 bar 数据库中名为 foo 的集合的命名空间为 bar.foo_id 上的索引因此具有命名空间 bar.foo._id_。重命名集合(应该)在它知道的所有命名空间上执行前缀搜索和替换,类似于 --nsFrom--nsTo options to mongorestore
代价可能是巨大的! docs.mongodb.com/manual/reference/command/renameCollection/… 如果目标数据库与源数据库相同,renameCollection 只会更改命名空间。这是一个快速操作。如果目标数据库与源数据库不同,renameCollection 会将源集合中的所有文档复制到目标集合。根据集合的大小,这可能需要更长的时间才能完成。
请改变你的答案。您的回答很有帮助,因为可以使用此命令将集合移动到另一个数据库。但这是不正确的,它可能会误导其他人。
a
amcgregor

没有重命名数据库的机制。 currently accepted answer at time of writing 实际上是正确的,并提供了一些关于上游借口的有趣背景细节,但没有提供复制行为的建议。其他答案指向 copyDatabase,它不再是 the functionality has been removed in 4.0 的选项。我更新了 SERVER-701 with my notes 和怀疑。 🙃

等效的行为涉及到 mongodumpmongorestore 的一段舞蹈:

导出您的数据,记下正在使用的“命名空间”。例如,在我的一个数据集上,我有一个名称空间为 byzmcbehoomrfjcs9vlj.Analytics 的集合——下一步将需要该前缀(实际上是数据库名称)。导入您的数据,提供 --nsFrom 和 --nsTo 参数。 (文档。)继续我上面假设的(并且非常难以理解)的例子,为了恢复到一个更有意义的名字,我调用:

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

有些人可能还会指出 mongorestore 的 --db 参数,但是这也已被弃用,并会触发警告,禁止在非 BSON 文件夹备份上使用,并给出对“use --nsInclude instead”的完全错误建议。上面的命名空间转换等效于使用 --db 选项,并且是正确的命名空间操作设置,因为我们没有尝试过滤正在恢复的内容。


带有 nsFrom/To 的 mongodump 是截至 2020 年的官方答案
链接的文档部分 amcgregor 也有一个使用管道 mongodump --archive --db=test | mongorestore --archive --nsFrom='test.*' --nsTo='examples.*' 的单行示例
m
madan ram

上述过程很慢,您可以使用以下方法,但您需要将集合逐个移动到另一个数据库。

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

很好的建议恕我直言。但是,值得注意的是,这不会从原始数据库中释放空间,但重命名应该比复制数据快得多。
从头开始,它确实会进行复制(因为它不会删除空格,所以它并不是真正简单的重命名),因此这种方法与复制和删除相比没有真正的优势。
A
Abhishek kumar

我试着做。

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/

这是基于 deprecation docs 的官方方法。
C
Cœur

如果您将所有数据都放在管理数据库中(您不应该这样做),您会注意到 db.copyDatabase() 不起作用,因为您的用户需要很多您可能不想授予它的权限。这是手动复制数据库的脚本:

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

db.copyDatabase 不再在 mongodb 4.4 上
我认为这不会复制索引