将MongoDB集合的子集保存到另一个集合
我有一套这样的
{date: 20120101} {date: 20120103} {date: 20120104} {date: 20120005} {date: 20120105}
如何将date“20120105”的这些文档的子集保存到另一个集合?
即 db.subset.save(db.full_set.find({date: "20120105"}));
这是shell版本:
db.full_set.find({date:"20120105"}).forEach(function(doc){ db.subset.insert(doc); });
注意:从MongoDB 2.6开始,聚合框架可以更快地完成这个任务。 看到黑色的答案的细节。
作为一个更新的解决scheme,我build议使用聚合框架来解决这个问题:
db.full_set.aggregate([ { $match: { date: "20120105" } }, { $out: "subset" } ]);
至less在我的情况下,它的工作速度比每个人快100倍。 这是因为整个聚合pipe道在mongod进程中运行,而基于find()
和insert()
的解决scheme必须将所有文档从服务器发送到客户端,然后再发回。 即使服务器和客户端在同一台机器上,性能也会受到影响。
实际上,在MongoDB中有一个相当于SQL的insert into ... select from
。 首先,您将多个文档转换为一个文档数组; 然后将数组插入到目标集合中
db.subset.insert(db.full_set.find({date:"20120105"}).toArray())
最一般的解决scheme是这样的:
利用聚合(@melan给出的答案):
db.full_set.aggregate({$match:{your query here...}},{$out:"sample"}) db.sample.copyTo("subset")
即使在操作之前有“子集”中的文档,并且您希望保留这些“旧”文档并只是插入一个新的子集,它也可以工作。
必须小心,因为copyTo()
命令将replace具有相同_id
的文档。
SQL的insert into ... select from ...
没有直接的相当于insert into ... select from ...
。
你必须自己照顾它。 获取感兴趣的文档并将其保存到另一个集合中。
你可以在shell中做,但是我会在Ruby中使用一个小的外部脚本。 像这样的东西:
require 'mongo' db = Mongo::Connection.new.db('mydb') source = db.collection('source_collection') target = db.collection('target_collection') source.find(date: "20120105").each do |doc| target.insert doc end