MongoDB:使用MongoShell将所选数据从一台主机/计算机复制到另一台主机/计算机

MongoDB:使用MongoShell将所选数据从一台主机/计算机复制到另一台主机/计算机,mongodb,Mongodb,我在不同的机器上有两个mongo数据库,host1:27017/db1和host2:27017/db2,在两个数据库上都有相同的集合item。例如,如何复制选定的数据 db1.item.find({"date": { $gte : "2016-03-15" }}) 使用mongoshell从db1.item到db2.item。我不想克隆集合(因为它们很大),只想复制选定的数据。我确实觉得mongodump&mongorestore是更普遍的方法。尽管如此,我还是找到了一种通过mongo she

我在不同的机器上有两个mongo数据库,
host1:27017/db1
host2:27017/db2
,在两个数据库上都有相同的集合
item
。例如,如何复制选定的数据

db1.item.find({"date": { $gte : "2016-03-15" }})

使用mongoshell从
db1.item
db2.item
。我不想克隆集合(因为它们很大),只想复制选定的数据。

我确实觉得
mongodump
&
mongorestore
是更普遍的方法。尽管如此,我还是找到了一种通过mongo shell(避免任何临时转储文件)来完成这一切的方法,这正是我所寻找的

[user@host1 ~]$ mongo
use db1;

var host2db2 = connect("host2:27017/db2")

host2db2.item.find({
    "date" : { $gte : "2016-03-15"}
}).forEach(function(doc){
    db1.item.insert(doc);
});

归功于:

我确实觉得
mongodump
mongorestore
是更普遍的方法。尽管如此,我还是找到了一种通过mongo shell(避免任何临时转储文件)来完成这一切的方法,这正是我所寻找的

[user@host1 ~]$ mongo
use db1;

var host2db2 = connect("host2:27017/db2")

host2db2.item.find({
    "date" : { $gte : "2016-03-15"}
}).forEach(function(doc){
    db1.item.insert(doc);
});
归功于:

因此,尽管使用shell是“可能的”(没有人说不是),但这并不是“最好的”方式

使用查询进行转储和恢复 “最佳”方法是使用和。您也不需要“临时转储文件”。这只是从一个输出到另一个输出的“管道”问题:

根据您实际从哪个主机运行此操作,以及将
-h
选项放置在何处:

mongodump-h host2-ddb2-c项\
--查询{“日期”:{“$gte”:“2016-03-15”}\
--出-\
|mongorestore-d db1-c项目-
在MongoDB 3.2版本中,这些命令也可以使用压缩数据。这需要以下方面和选项:

mongodump-h host2-ddb2-c项\
--查询{“日期”:{“$gte”:“2016-03-15”}\
--gzip——归档\
|mongorestore-ddb1-c项--gzip--archive
这始终是在数据库之间,特别是主机之间移动内容的最快方式

使用外壳 如果你坚持把它写在shell中,那么你至少应该把它写对

当然,您可以使用或方法来引用远程连接,但这实际上只是故事的一部分,因为一旦连接,您仍然需要有效地处理此问题

最好的方法是使用“批量操作”,因为这样可以消除对目标服务器和集合执行的每个新
.insert()
操作的请求和确认开销。这将减少大量的时间,尽管仍然不如上述实用程序的使用效率:

现代MongoDB 3.2具有:

var db2=connect('host2/db2');
var操作=[];
db2.item.find({“date”:{“$gte”:“2016-03-15”}).forEach(函数(doc){
push({“insertOne”:{“document”:doc});
//实际上一次只写1000个条目
if(operations.length==1000){
bulkWrite(操作,{“ordered”:false})
操作=[];
}
});
//写下任何剩余的
if(operations.length>0){
bulkWrite(操作,{“ordered”:false});
}
对于MongoDB 2.6版本,还有另一个构造函数:

var db2=connect('host2/db2');
var bulk=db.item.initializeUnderedBulkop();
var计数=0;
db2.item.find({“date”:{“$gte”:“2016-03-15”}).forEach(函数(doc){
批量插入(doc);
计数++;
如果(计数%1000==0){
bulk.execute();
bulk=db.item.initializeUnderedBulkop();
}
});
如果(计数%1000!=0){
bulk.execute();
}
当然,较新的方法实际上只是调用相同的底层“旧”方法。但主要的一点是在其他API中的一致性,在使用低于MongoDB 2.6的服务器版本(该版本没有“批量操作”wire协议)时,经常需要“降级”操作,然后只为您处理批处理中每个操作的循环和提交

无论哪种情况,这种方法都是最好的,因为操作实际上是以“并行”而不是“串行”的方式在服务器上提交的,这意味着多个东西实际上是同时写入的

结论 所以实际上,所有这些都是如何在外部实用程序中实现代码的,实际上是以一种更有组织的“低级”形式实现的。当然,“shell”不会通过主机间的通信“在线”压缩数据,也不会访问BSON库和低级代码可以实现的“低级”写函数,这两种功能都工作得更快

“转储和恢复”实际上可以直接使用压缩的BSON形式的数据,并以非常高效的方式提交写操作。因此,这是您最好的选择,而不是自己编写实现。

因此,尽管使用shell“可能”(没有人说不是),但这并不是“最好”的方式

使用查询进行转储和恢复 “最佳”方法是使用和。您也不需要“临时转储文件”。这只是从一个输出到另一个输出的“管道”问题:

根据您实际从哪个主机运行此操作,以及将
-h
选项放置在何处:

mongodump-h host2-ddb2-c项\
--查询{“日期”:{“$gte”:“2016-03-15”}\
--出-\
|mongorestore-d db1-c项目-
在MongoDB 3.2版本中,这些命令也可以使用压缩数据。这需要以下方面和选项:

mongodump-h host2-ddb2-c项\
--查询{“日期”:{“$gte”:“2016-03-15”}\
--gzip——归档\
|mongorestore-ddb1-c项--gzip--archive
这始终是在数据库之间,特别是主机之间移动内容的最快方式

使用外壳 如果你坚持把它写在shell中,那么你至少应该把它写对

当然,您可以使用或方法来引用远程连接,但这实际上只是故事的一部分,因为一旦连接,您仍然需要处理这个问题