将MongoDB集合的子集保存到另一个集合

时间:2012-03-14 22:52:41

标签: mongodb

我有一套这样的

{date: 20120101}
{date: 20120103}
{date: 20120104}
{date: 20120005}
{date: 20120105}

如何将日期为'20120105'的那些文档的子集保存到另一个集合?

db.subset.save(db.full_set.find({date: "20120105"}));

6 个答案:

答案 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操作尚不存在,则它在当前数据库中创建一个新集合。
  • 在聚合完成之前,集合不可见。
  • 如果聚合失败,则MongoDB不会创建集合。

语法:

{ $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" }
]);