问题
I am trying to copy a collection through the shell, but I am getting an 'unauthorized' error, despite having read/write permissions. Specifically:
db.createCollection("ITISAFAKE")
{ "ok" : 1 }
db.ITISAFAKE.insert({"Is it a fake?": true})
db.ITISAFAKE.find()
{ "_id" : ObjectId("52d5e51d4bb0851f985f69d8"), "Is it a fake?" : true }
db.ITISAFAKE.drop()
true
Yay that works fine. However:
db.createCollection("FAKE")
{ "ok" : 1 }
db.FAKE.insert({senator: true})
db.FAKE.copyTo("FAKERY")
Tue Jan 14 17:36:26.188 { "ok" : 0, "errmsg" : "unauthorized" } at src/mongo/shell/db.js:571
So, I could solve this problem by literally copying things over record by record, but that seems dumb. I can fiddle with user permissions etc, but how do I ... actually just copy things?
回答1:
Per the collection.copyTo() documentation in MongoDB 2.4, this shell helper "copies all documents from collection into newCollection using server-side JavaScript".
I expect the reason you are getting an unauthorized
error is because the server-side db.eval() command requires full admin permissions in MongoDB 2.4 (multiple roles on the admin
database).
You can actually see the source for this helper in the mongo
shell if you invoke copyTo()
without the ()
:
> db.test.copyTo
function ( newName ){
return this.getDB().eval(
function( collName , newName ){
var from = db[collName];
var to = db[newName];
to.ensureIndex( { _id : 1 } );
var count = 0;
var cursor = from.find();
while ( cursor.hasNext() ){
var o = cursor.next();
count++;
to.save( o );
}
return count;
} , this.getName() , newName
);
}
Due to the use of server-side db.eval()
, there are several significant warnings on copyTo()
usage including cautions on type fidelity and locking issues. I believe this helper is only intended to be used in development environments with more open permissions, rather than a production environment.
DIY copy from the mongo
shell
So, I could solve this problem by literally copying things over record by record
That's not an entirely crazy option :). Here is a simple one-liner for the mongo
shell (replace source
and target
collections as appropriate):
db.source.find().forEach( function(d) {db.target.insert(d)});
If you are concerned about network bandwidth you can run this from a mongo
shell which is local to your MongoDB server.
Copy with mongodump
/ mongorestore
A better approach to copying a collection (although not directly from the mongo
shell) would be to use mongodump
& mongorestore
:
$ mongodump -d test -c source
$ mongorestore -d test -c target dump/test/source.bson
来源:https://stackoverflow.com/questions/21128079/mongo-copy-collection-and-user-permissions