267

有没有一种简单的方法可以做到这一点?

4

22 回答 22

351

最好的方法是做一个mongodumpthen mongorestore。您可以通过以下方式选择集合:

mongodump -d some_database -c some_collection

[可选地,压缩转储 ( zip some_database.zip some_database/* -r) 并将scp其压缩到其他地方]

然后恢复它:

mongorestore -d some_other_db -c some_or_other_collection dump/some_collection.bson

中的现有数据some_or_other_collection将被保留。这样,您就可以将集合从一个数据库“附加”到另一个数据库。

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

于 2012-07-19T06:09:43.353 回答
250

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

您可以执行以下操作:

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

请注意,这样,两个数据库需要共享同一个 mongod 才能工作。

除此之外,您可以对一个数据库中的集合进行 mongodump,然后将集合 mongorestore 到另一个数据库。

于 2012-07-19T06:13:49.917 回答
117

实际上,有一个命令可以集合从一个数据库移动到另一个数据库。它只是不称为“移动”或“复制”。

要复制一个集合,您可以在同一个数据库上克隆它,然后移动克隆的集合。

克隆:

> use db1
switched to db db1

> db.source_collection.find().forEach(
      function(x){
          db.collection_copy.insert(x)
      }
  );

移动:

> use admin
switched to db admin

> db.runCommand(
      {
          renameCollection: 'db1.source_collection',
          to              : 'db2.target_collection'
      }
  );

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

于 2013-04-29T11:51:14.303 回答
26

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

use test
var db2 = connect('localhost:27017/test2')

正常查找并将前 20 条记录复制到 test2。

db.customer.find().limit(20).forEach(function(p) { db2.customer.insert(p); });

或按某些标准过滤

db.customer.find({"active": 1}).forEach(function(p) { db2.customer.insert(p); });

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

于 2012-07-31T01:54:39.780 回答
21

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

{ cloneCollection: "<collection>", from: "<hostname>", query: { <query> }, copyIndexes: <true|false> } 

请参阅http://docs.mongodb.org/manual/reference/command/cloneCollection/

于 2013-10-16T13:07:25.823 回答
20

我通常会这样做:

use sourcedatabase;
var docs=db.sourcetable.find();
use targetdatabase;
docs.forEach(function(doc) { db.targettable.insert(doc); });
于 2013-08-20T02:19:26.027 回答
12

对于大型集合,您可以使用Bulk.insert()

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

这将节省大量时间。就我而言,我正在复制包含 1219 个文档的集合:iter vs Bulk (67 secs vs 3 secs)

于 2018-08-30T03:32:45.870 回答
6

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

db.oldCollection.aggregate([{$out : "newCollection"}])

应该注意的是,oldCollection 中的索引不会复制到 newCollection 中。

于 2015-09-11T08:14:18.153 回答
5

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

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

@bens 答案也是一个很好的答案,不仅适用于集合的热备份,而且 mongorestore 不需要共享同一个 mongod。

于 2012-07-19T13:12:12.223 回答
5

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

db.coll.mapReduce(function() { emit(this._id, this); }, function(k,vs) { return vs[0]; }, { out : "coll2" })
于 2013-06-25T23:22:11.950 回答
5

使用 pymongo,您需要在同一个 mongod 上拥有两个数据库,我做了以下操作:


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

cursor = db["<collection to copy from>"].find()
for data in cursor:
    db2["<new collection>"].insert(data)
于 2017-05-24T17:11:13.383 回答
5

有不同的方法来做收藏副本。请注意,复制可以发生在同一个数据库、不同的数据库、分片数据库或mongod实例中。一些工具可以有效地用于大型集合复制。

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

使用 $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),使用适当的驱动程序软件编写程序来执行复制 - 这可能涉及使用查找和插入操作或其他方法。这个查找插入也可以从mongoshell 中执行。

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

于 2020-09-19T06:29:38.290 回答
4

正如其他答案中给出的那样,最快的解决方案应该是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=-

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

sh.shardCollection("some_or_other_database.some_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("some_or_other_database.some_or_other_collection", chunk.min)
})
于 2021-04-13T15:04:13.520 回答
3

如果 RAM 不是问题,则使用insertManyforEach循环快得多。

var db1 = connect('<ip_1>:<port_1>/<db_name_1>')
var db2 = connect('<ip_2>:<port_2>/<db_name_2>')

var _list = db1.getCollection('collection_to_copy_from').find({})
db2.collection_to_copy_to.insertMany(_list.toArray())
于 2018-06-28T05:39:41.537 回答
2

这不会解决您的问题,但是 mongodb shell 有一种方法可以将集合复制到同一数据库中的copyTo另一个集合中:

db.mycoll.copyTo('my_other_collection');

它还从 BSON 转换为 JSON,因此mongodump/mongorestore是最好的方法,正如其他人所说的那样。

于 2013-09-11T09:57:00.663 回答
1

您可以随时使用 Robomongo。从 v0.8.3 开始,有一个工具可以通过右键单击集合并选择“将集合复制到数据库”来执行此操作

详情见http://blog.robomongo.org/whats-new-in-robomongo-0-8-3/

此功能在 0.8.5 中已被删除,因为它存在漏洞,因此如果您想试用,则必须使用 0.8.3 或 0.8.4。

于 2013-12-09T18:33:25.230 回答
1

万一有些heroku用户在这里绊倒了,像我一样想将一些数据从临时数据库复制到生产数据库,反之亦然,这就是你如何非常方便地做到这一点(注意我希望那里没有错别字,不能在atm检查它。,我会尽快确认代码的有效性):

to_app="The name of the app you want to migrate data to"
from_app="The name of the app you want to migrate data from"
collection="the collection you want to copy"
mongohq_url=`heroku config:get --app "$to_app" MONGOHQ_URL`
parts=(`echo $mongohq_url | sed "s_mongodb://heroku:__" | sed "s_[@/]_ _g"`)
to_token=${parts[0]}; to_url=${parts[1]}; to_db=${parts[2]}
mongohq_url=`heroku config:get --app "$from_app" MONGOHQ_URL`
parts=(`echo $mongohq_url | sed "s_mongodb://heroku:__" | sed "s_[@/]_ _g"`)
from_token=${parts[0]}; from_url=${parts[1]}; from_db=${parts[2]}
mongodump -h "$from_url" -u heroku -d "$from_db" -p"$from_token" -c "$collection" -o col_dump
mongorestore -h "$prod_url" -u heroku -d "$to_app" -p"$to_token" --dir col_dump/"$col_dump"/$collection".bson -c "$collection"
于 2014-09-28T09:48:53.067 回答
1

通过单击数据库、集合或特定集合下载链接,使用具有导出和导入工具的“Studio3T for MongoDB”:https ://studio3t.com/download/

于 2019-01-27T07:29:20.773 回答
1

这里有很多正确的答案。我会以管道mongodumpmongorestore方式购买大型收藏品:

mongodump --db fromDB --gzip --archive | mongorestore --drop --gzip --archive --nsFrom "fromDB.collectionName" --nsTo "toDB.collectionName"

虽然如果我想做快速复制,它很慢但它有效:

use fromDB 
db.collectionName.find().forEach(function(x){
   db.getSiblingDB('toDB')['collectionName'].insert(x);
});"
于 2021-10-29T10:22:01.250 回答
0

就我而言,我必须在新集合中使用旧集合中的属性子集。所以我最终在新集合上调用 insert 时选择了这些属性。

db.<sourceColl>.find().forEach(function(doc) { 
    db.<newColl>.insert({
        "new_field1":doc.field1,
        "new_field2":doc.field2,
        ....
    })
});`
于 2016-06-24T18:06:11.560 回答
0

要将集合 (myCollection1) 从一个数据库复制到 MongoDB 中的另一个数据库,

**Server1:**
myHost1.com 
myDbUser1
myDbPasword1
myDb1
myCollection1

outputfile:
myfile.json 

**Server2:**
myHost2.com 
myDbUser2
myDbPasword2
myDb2
myCollection2 

你可以这样做:

mongoexport  --host myHost1.com --db myDb1 -u myDbUser1  -p myDbPasword1 --collection myCollection1   --out  myfile.json 

然后:

mongoimport  --host myHost2.com --db myDb2 -u myDbUser2  -p myDbPasword2 --collection myCollection2   --file myfile.json 

另一种情况,使用 CSV 文件:

Server1:
myHost1.com 
myDbUser1
myDbPasword1
myDb1
myCollection1
fields.txt
    fieldName1
    fieldName2

outputfile:
myfile.csv

Server2:
myHost2.com 
myDbUser2
myDbPasword2
myDb2
myCollection2

你可以这样做:

mongoexport  --host myHost1.com --db myDb1 -u myDbUser1  -p myDbPasword1 --collection myCollection1   --out  myfile.csv --type=csv

在 csv 文件 (name1.decimal(),name1.string()..) 中添加 clolumn 类型,然后:

mongoimport  --host myHost2.com --db myDb2 -u myDbUser2  -p myDbPasword2 --collection myCollection2   --file myfile.csv --type csv --headerline --columnsHaveTypes
于 2021-06-04T03:50:40.830 回答
-2

这可以使用 Mongo 的db.copyDatabase方法来完成:

db.copyDatabase(fromdb, todb, fromhost, username, password)

参考:http ://docs.mongodb.org/manual/reference/method/db.copyDatabase/

于 2014-11-18T16:02:09.213 回答