Saving the result of a MongoDB query

倖福魔咒の 提交于 2019-12-09 12:35:27

问题


When doing a research in mongo shell I often write quite complex queries and want the result to be stored in other collection. I know the way to do it with .forEach():

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

But it's kind of tedious to write that stuff each time. Is there a cleaner way? I'd like the syntax to be something like db.documents.find(query).dumpTo('collectionName').


回答1:


Here's a solution I'll use: db.results.insert(db.docs.find(...).toArray())

There is still too much noise, though.

UPD: There is also an option to rewrite find using aggregation pipeline. Then you can use $out operator.




回答2:


It looks like you are doing your queries from the mongo shell, which allows you to write code in javascript. You can assign the result of queries to a variable:

result = db.mycollection.findOne(my_query)

And save the result to another collection:

db.result.save(result)

You might have to remove the _id of the result if you want to append it to the result collection, to prevent a duplicate key error

Edit:

db.mycollection.findOne({'_id':db.mycollection.findOne()['_id']})
db.foo.save(db.bar.findOne(...))

If you want to save an array, you can write a javascript function. Something like the following should work (I haven't tested it):

function save_array(arr) {
    for(var i = 0; i < arr.length; i++) {
        db.result.save(arr[i])
    }
}

...

result = db.mycollection.find(...)
save_array(result)

If you want the function to be available every time you start mongo shell, you can include it in your .mongorc.js file




回答3:


As far as I know, there isn't built-in functionality to do this in MongoDB.

Other options would be to use mongoexport/mongoimport or mongodump/mongorestore functionalities.

In both mongoexport and mongodump you can filter the results by adding query options using --query <JSON> or -q <JSON>.




回答4:


If your query is using an aggregation operator then the solution is as sample as using the $out.

I created a sample Collection with the name "tester" which contain the following records.

{ "_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"}

Now using the aggregate operator I perform a group by and then save the result into a new collection using this magical operator "$out".

db.tester.aggregate([{$group:{
                                _id:{name:"$name",state:"$state"},
                                min:{$min:"$value"},
                                max:{$max:"$value"},
                               } },
                       {$out:"tester_max_min"}
                     ])

What basically the query is trying to do is, group by name & state and find the min and max values for each individual group, and then save the result into a new collection named "tester_max_min"

db.tester_max_min.find();

The new collection formed will have the following documents in it :

{ "_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 }

I still need to explore how helpful can $out is but it works like a charm for any aggregator operator.



来源:https://stackoverflow.com/questions/20769621/saving-the-result-of-a-mongodb-query

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!