保存MongoDB查询结果

11
在使用mongo shell进行研究时,我经常编写相当复杂的查询,并希望将结果存储在其他集合中。我知道使用.forEach()的方法:

db.documents.find(query).forEach(function(d){db.results.insert(d)})

但每次都编写这些内容有点繁琐。是否有更简洁的方式?我想要的语法类似于 db.documents.find(query).dumpTo('collectionName')

4个回答

12

这里有一个我将使用的解决方案:db.results.insert(db.docs.find(...).toArray())

不过还是有太多噪音。

更新:还有一种使用聚合管道重写find的选择。然后你可以使用$out操作符


6

看起来你正在使用mongo shell进行查询,该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文件中。


好,但我根本不想使用.forEach。如果我能够执行db.result.save(db.docs.find(...))就太好了,但它会提示“无法保存DBQuery”。 - vorou
1
我认为你尝试失败的原因是内部的db.docs.find查询返回的是一个数组而不是一个文档。Save可以保存一个文档。请参见编辑。 - Mzzl
谢谢,我已经发现 DBQuery.toArray() 方法可以实现我想要的功能。 - vorou
我在保存数组方面遇到了问题,我使用了以下方法:function save_array(arr) { arr.forEach(element => db.result.save(element)); }; - Jesús Sánchez

1
如果您的查询使用聚合操作符,则解决方案就像使用 $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的实用性,但它对于任何聚合运算符都非常有效。


如果$out指向与聚合相同的集合,它将完全替换原始集合,因此如果存在$match过滤器,则未匹配的所有内容都将被删除。 - user323774

1
据我所知,在MongoDB中没有内置功能来实现这一点。
其他选项是使用mongoexport/mongoimportmongodump/mongorestore功能。
在mongoexport和mongodump中,您可以通过添加查询选项--query <JSON>-q <JSON> 来过滤结果。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接