Ben*_*Ben 272

最好的方法是做一个mongodump然后mongorestore.

您可以通过以下方式选择集合:

mongodump -d some_database -c some_collection
Run Code Online (Sandbox Code Playgroud)

[可选,将dump(zip some_database.zip some_database/* -r)和scp它压缩到别处]

然后恢复它:

mongorestore -d some_other_db -c some_or_other_collection dump/some_collection.bson
Run Code Online (Sandbox Code Playgroud)

some_or_other_collection将保留现有数据.这样,您可以将一个集合从一个数据库"追加"到另一个数据库.

在2.4.3版之前,您还需要在复制数据后添加索引.从2.4.3开始,此过程是自动的,您可以使用它来禁用它--noIndexRestore.

  • 它适用于PW保护的数据库,您只需要在参数中传递auth (3认同)
  • 这比find/forEach/insert快得多,在我的情况下是2分钟vs 2小时 (2认同)
  • 使用 --username 但不使用 --password 传递数据库的用户名,以获取密码提示。最好不要将密码放在命令行上(最终将其保存到 .bash_history 或类似文件中) (2认同)

小智 191

目前MongoDB中没有命令可以执行此操作.请注意带有相关功能要求JIRA机票.

你可以这样做:

db.<collection_name>.find().forEach(function(d){ db.getSiblingDB('<new_database>')['<collection_name>'].insert(d); });
Run Code Online (Sandbox Code Playgroud)

请注意,有了这个,两个数据库将需要共享相同的mongod才能工作.

除此之外,您可以从一个数据库执行集合的mongodump,然后将集合mongorestore存储到另一个数据库.

  • 请注意,如果您[在JS shell中复制](http://docs.mongodb.org/manual/faq/developers/#how-do-you-copy-all-objects-from-one-collection-to-another )BSON文档在此过程中被解码为JSON,因此某些文档可能会发生类型更改.mongodump/mongorestore通常是更好的方法. (13认同)
  • 谢谢.请注意,代码中有拼写错误,而不是关闭getSiblingDB函数.以下是更正后的代码:db.<collection_name> .find().forEach(function(d){db.getSiblingDB('<new_database>')['<collection_name>'].insert(d);}); (2认同)
  • 这对于大量收藏有效吗? (2认同)

Anu*_*pta 89

其实,有一个命令移动从一个数据库收集到另一个.它不被称为"移动"或"复制".

要复制集合,可以在同一个db上克隆它,然后移动克隆.

要克隆:

> use db1
> db.source_collection.find().forEach( function(x){db.collection_copy.insert(x)} );
Run Code Online (Sandbox Code Playgroud)

移动:

> use admin
switched to db admin
> db.runCommand({renameCollection: 'db1.source_collection', to: 'db2.target_collection'}) // who'd think rename could move?
Run Code Online (Sandbox Code Playgroud)

其他答案更适合复制集合,但如果您想要移动它,这尤其有用.

  • 而不是"使用admin"后跟"db.runCommand(..."你只能执行一个命令,"db.adminCommand(..." (4认同)
  • Thx很棒!在''db1.source_collection'中只需要一个关闭的撇号 (3认同)

小智 24

我会滥用mongo cli mongo doc中的connect函数.这意味着您可以启动一个或多个连接.如果要将客户集合从test复制到同一服务器上的test2.首先你启动mongo shell

use test
var db2 = connect('localhost:27017/test2')
Run Code Online (Sandbox Code Playgroud)

做一个正常的查找并将前20条记录复制到test2.

db.customer.find().limit(20).forEach(function(p) { db2.customer.insert(p); });
Run Code Online (Sandbox Code Playgroud)

或按某些标准过滤

db.customer.find({"active": 1}).forEach(function(p) { db2.customer.insert(p); });
Run Code Online (Sandbox Code Playgroud)

只需将localhost更改为IP或主机名即可连接到远程服务器.我用它将测试数据复制到测试数据库进行测试.

  • 正如我对Jason的建议所评论的那样,请注意,如果您在JS shell中复制,BSON文档在此过程中会被解码为JSON,因此某些文档可能会发生类型更改.[限制评估]有类似的考虑因素(http://www.mongodb.org/display/DOCS/Server-side+Code+Execution#Server-sideCodeExecution-Limitationsof%7B%7Beval%7D%7D)这是在数据库之间(特别是在同一台服务器上)复制大量数据的过程会变慢.所以mongodump/mongorestore FTW :). (4认同)

es *_*gne 20

如果在两个远程mongod实例之间,请使用

{ cloneCollection: "<collection>", from: "<hostname>", query: { <query> }, copyIndexes: <true|false> } 
Run Code Online (Sandbox Code Playgroud)

http://docs.mongodb.org/manual/reference/command/cloneCollection/

  • 在db.runCommand()中包装,即db.runCommand({cloneCollection:"<collection>",from:"<hostname>",query:{<query>}}) (5认同)

ame*_*iel 18

我通常会这样做:

use sourcedatabase;
var docs=db.sourcetable.find();
use targetdatabase;
docs.forEach(function(doc) { db.targettable.insert(doc); });
Run Code Online (Sandbox Code Playgroud)


Wer*_*eit 12

令人难以置信的是,对于缓慢得令人痛苦的逐一数据副本,有多少人投了赞成票。

正如其他答案中给出的,最快的解决方案应该是mongodump / mongorestore。无需将转储保存到本地磁盘,您可以将转储直接通过管道传送到 mongorestore:

mongodump --db=some_database --collection=some_collection --archive=- | mongorestore --nsFrom="some_database.some_collection" --nsTo="some_or_other_database.some_or_other_collection" --archive=-
Run Code Online (Sandbox Code Playgroud)

如果您运行分片集群,则默认情况下不会对新集合进行分片。所有数据最初都会写入您的主分片。这可能会导致磁盘空间出现问题,并给集群带来额外的负载以进行平衡。在导入数据之前,最好像这样预先分割您的集合:

sh.shardCollection("same_or_other_database.same_or_other_collection", { <shard_key>: 1 });
db.getSiblingDB("config").getCollection("chunks").aggregate([
   { $match: { ns: "some_database.some_collection"} },
   { $sort: { min: 1 } },
   { $skip: 1 }
], { allowDiskUse: true }).forEach(function (chunk) {
   sh.splitAt("same_or_other_database.same_or_other_collection", chunk.min)
})
Run Code Online (Sandbox Code Playgroud)


pra*_*ad_ 9

进行集合复制有多种方法。请注意,复制可以发生在同一数据库、不同数据库、分片数据库或mongod实例中。某些工具对于大型集合复制非常有效。

Aggregation with $merge: 将聚合管道的结果写入指定的集合。请注意,复制可以跨数据库进行,甚至可以跨分片集合。创建一个新集合或替换现有集合。4.2 版本中的新功能。例子:db.test.aggregate([ { $merge: { db: "newdb", coll: "newcoll" }} ])

Aggregation with $out: 将聚合管道的结果写入指定的集合。请注意,复制只能发生在同一数据库内。创建一个新集合或替换现有集合。例子:db.test.aggregate([ { $out: "newcoll" } ])

mongoexport 和 mongoimport: 这些是命令行工具。 mongoexport生成集合数据的 JSON 或 CSV 导出。导出的输出用作使用mongoimport.

mongodump 和 mongorestore: 这些是命令行工具。 mongodump实用程序用于创建数据库或集合内容的二进制导出。该mongorestore程序将数据从创建的二进制数据库转储加载mongodump到目标中。

db.cloneCollection(): 将集合从远程mongod实例复制到当前mongod实例。自 4.2 版本起已弃用。

db.collection.copyTo(): 将集合中的所有文档复制到新的集合中(在同一数据库内)。自 3.0 版本起已弃用。从版本 4.2 开始,MongoDB 此命令无效。

注意:除非另有说明,否则上述命令从mongoshell 运行。

参考: MongoDB 手册

您还可以使用最喜欢的编程语言(例如,Java)或环境(例如,NodeJS),使用适当的驱动程序软件来编写程序来执行复制 - 这可能涉及使用查找和插入操作或其他方法。也可以从 shell 执行此查找插入操作mongo

您还可以使用 MongoDB Compass 等 GUI 程序进行集合复制。

  • `$merge` 需要 "into": `db.test.aggregate([ { $merge: { into: { db: "newdb", coll: "newcoll" } } } ])` https://www.mongodb。 com/docs/v4.4/reference/operator/aggregation/merge/ (2认同)

nam*_*tal 7

对于庞大的集合,可以使用Bulk.insert()

var bulk = db.getSiblingDB(dbName)[targetCollectionName].initializeUnorderedBulkOp();
db.getCollection(sourceCollectionName).find().forEach(function (d) {
    bulk.insert(d);
});
bulk.execute();
Run Code Online (Sandbox Code Playgroud)

这样可以节省很多时间。就我而言,我要复制包含1219个文档的集合:iter vs Bulk(67秒vs 3秒)


Sam*_*aye 5

我知道这个问题已经得到解答但是我个人不会做@JasonMcCays的回答,因为游标流是这样的,如果仍在使用该集合,这可能会导致无限的游标循环.相反,我会使用快照():

http://www.mongodb.org/display/DOCS/How+to+do+Snapshotted+Queries+in+the+Mongo+Database

@bens答案也是一个很好的答案,适用于集合的热备份,不仅如此,但mongorestore不需要共享相同的mongod.


Vaj*_*ecz 5

这可能只是一个特例,但是对于包含两个随机字符串字段(长度为15-20个字符)的100k文档的集合,使用愚蠢的mapreduce几乎是find-insert/copyTo的两倍:

db.coll.mapReduce(function() { emit(this._id, this); }, function(k,vs) { return vs[0]; }, { out : "coll2" })
Run Code Online (Sandbox Code Playgroud)


小智 5

您可以使用聚合框架来解决您的问题

db.oldCollection.aggregate([{$out : "newCollection"}])
Run Code Online (Sandbox Code Playgroud)

需要注意的是,oldCollection中的索引不会复制到newCollection中.


vbh*_*kta 5

使用pymongo,您需要将两个数据库都放在同一个mongod上,我做了以下工作:


db =原始数据库
db2 =要复制到的数据库

cursor = db["<collection to copy from>"].find()
for data in cursor:
    db2["<new collection>"].insert(data)
Run Code Online (Sandbox Code Playgroud)

  • 如果数据量很大,这将需要很多时间。或者,您可以使用 [bulk_insert](https://docs.mongodb.com/manual/reference/method/Bulk.insert/) (2认同)