在 mongo shell 中进行研究时,我经常编写非常复杂的查询并希望将结果存储在其他集合中。我知道这样做的方法.forEach()
:
db.documents.find(query).forEach(function(d){db.results.insert(d)})
但是每次写这些东西有点乏味。有没有更清洁的方法?我希望语法类似于db.documents.find(query).dumpTo('collectionName')
.
在 mongo shell 中进行研究时,我经常编写非常复杂的查询并希望将结果存储在其他集合中。我知道这样做的方法.forEach()
:
db.documents.find(query).forEach(function(d){db.results.insert(d)})
但是每次写这些东西有点乏味。有没有更清洁的方法?我希望语法类似于db.documents.find(query).dumpTo('collectionName')
.
这是我将使用的解决方案:db.results.insert(db.docs.find(...).toArray())
但是,仍然有太多的噪音。
UPD:还有一个find
使用聚合管道重写的选项。然后你可以使用$out
operator。
看起来您正在从 mongo shell 进行查询,它允许您在 javascript 中编写代码。您可以将查询结果分配给变量:
result = db.mycollection.findOne(my_query)
并将结果保存到另一个集合:
db.result.save(result)
如果要将结果附加到结果集合中,则可能必须删除结果的 _id,以防止重复键错误
编辑:
db.mycollection.findOne({'_id':db.mycollection.findOne()['_id']})
db.foo.save(db.bar.findOne(...))
如果要保存数组,可以编写一个 javascript 函数。像下面这样的东西应该可以工作(我没有测试过):
function save_array(arr) {
for(var i = 0; i < arr.length; i++) {
db.result.save(arr[i])
}
}
...
result = db.mycollection.find(...)
save_array(result)
如果您希望每次启动 mongo shell 时都可以使用该功能,则可以将其包含在.mongorc.js
文件中
据我所知,MongoDB 中没有内置功能可以做到这一点。
其他选择是使用mongoexport / mongoimport或mongodump / mongorestore功能。
在 mongoexport 和 mongodump 中,您可以通过使用--query <JSON>
or添加查询选项来过滤结果-q <JSON>
。
如果您的查询使用聚合运算符,则解决方案与使用 $out 一样。
我创建了一个名为“tester”的示例集合,其中包含以下记录。
{ "_id" : ObjectId("4fb36bfd3d1c88bfa15103b1"), "name" : "bob", "value" : 5, "state" : "b"}
{ "_id" : ObjectId("4fb36c033d1c88bfa15103b2"), "name" : "bob", "value" : 3, "state" : "a"}
{ "_id" : ObjectId("4fb36c063d1c88bfa15103b3"), "name" : "bob", "value" : 7, "state" : "a"}
{ "_id" : ObjectId("4fb36c0c3d1c88bfa1a03b4"), "name" : "john", "value" : 2, "state" : "a"}
{ "_id" : ObjectId("4fb36c103d1c88bfa5103b5"), "name" : "john", "value" : 4, "state" : "b"}
{ "_id" : ObjectId("4fb36c143d1c88bfa15103b"), "name" : "john", "value" : 8, "state" : "b"}
{ "_id" : ObjectId("4fb36c163d1c88bfa15103a"), "name" : "john", "value" : 6, "state" : "a"}
现在使用聚合运算符执行分组,然后使用这个神奇的运算符“$out”将结果保存到新集合中。
db.tester.aggregate([{$group:{
_id:{name:"$name",state:"$state"},
min:{$min:"$value"},
max:{$max:"$value"},
} },
{$out:"tester_max_min"}
])
基本上查询试图做的是,按名称和状态分组并找到每个单独组的最小值和最大值,然后将结果保存到一个名为“tester_max_min”的新集合中
db.tester_max_min.find();
形成的新集合将包含以下文件:
{ "_id" : { "name" : "john", "state" : "b" }, "min" : 4, "max" : 8 }
{ "_id" : { "name" : "john", "state" : "a" }, "min" : 2, "max" : 6 }
{ "_id" : { "name" : "bob", "state" : "a" }, "min" : 3, "max" : 7 }
{ "_id" : { "name" : "bob", "state" : "b" }, "min" : 5, "max" : 5 }
我仍然需要探索 $out 有多大帮助,但它对任何聚合器运营商来说都是一种魅力。