我有一套这样的
{date: 20120101}
{date: 20120103}
{date: 20120104}
{date: 20120005}
{date: 20120105}
如何将日期为'20120105'的那些文档的子集保存到另一个集合?
即 db.subset.save(db.full_set.find({date: "20120105"}));
答案 0 :(得分:79)
作为一种较新的解决方案,我建议使用聚合框架解决问题:
db.full_set.aggregate([ { $match: { date: "20120105" } }, { $out: "subset" } ]);
至少在我的情况下,它比forEach快100倍。这是因为整个聚合管道在mongod进程中运行,而基于find()
和insert()
的解决方案必须将所有文档从服务器发送到客户端然后再返回。即使服务器和客户端在同一台计算机上,这也会降低性能。
答案 1 :(得分:57)
这是shell版本:
db.full_set.find({date:"20120105"}).forEach(function(doc){
db.subset.insert(doc);
});
注意:从MongoDB 2.6开始,聚合框架可以更快地完成此任务;有关详细信息,请参阅梅兰的答案。
答案 2 :(得分:16)
实际上,MongoDB中有一个等价的SQL insert into ... select from
。首先,将多个文档转换为文档数组;然后将数组插入目标集合
db.subset.insert(db.full_set.find({date:"20120105"}).toArray())
答案 3 :(得分:14)
最通用的解决方案是:
利用聚合(@melan给出的答案):
db.full_set.aggregate({$match:{your query here...}},{$out:"sample"})
db.sample.copyTo("subset")
即使文件中包含"子集"在操作之前,你想保留那些" old"文档,只需在其中插入新的子集。
必须小心,因为copyTo()
命令用相同的_id
替换文档。
答案 4 :(得分:3)
没有SQL 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
答案 5 :(得分:1)
Mongodb与$ out运算符一起聚合,该运算符允许将子集保存到新集合中。以下是详细信息:
$ out 提取聚合管道返回的文档并将它们写入指定的集合。
语法:
{ $out: "<output-collection>" }
示例 藏书包含以下文档:
{ "_id" : 8751, "title" : "The Banquet", "author" : "Dante", "copies" : 2 }
{ "_id" : 8752, "title" : "Divine Comedy", "author" : "Dante", "copies" : 1 }
{ "_id" : 8645, "title" : "Eclogues", "author" : "Dante", "copies" : 2 }
{ "_id" : 7000, "title" : "The Odyssey", "author" : "Homer", "copies" : 10 }
{ "_id" : 7020, "title" : "Iliad", "author" : "Homer", "copies" : 10 }
以下聚合操作将书集中的数据转换为具有按作者分组的书名,然后将结果写入作者集。
db.books.aggregate( [
{ $group : { _id : "$author", books: { $push: "$title" } } },
{ $out : "authors" }
] )
操作后,authors集合包含以下文档:
{ "_id" : "Homer", "books" : [ "The Odyssey", "Iliad" ] }
{ "_id" : "Dante", "books" : [ "The Banquet", "Divine Comedy", "Eclogues" ] }
在询问的问题中,使用以下查询,您将在数据库中获得名为“ col_20120105”的新集合
db.products.aggregate([
{ $match : { date : "20120105" } },
{ $out : "col_20120105" }
]);