PHP的Mongo驱动程序缺少renameCommand函数。 There is reference通过管理数据库执行此操作。但是,如果没有对该数据库的登录权限,似乎更新版本的Mongo驱动程序不会让您“使用”管理数据库。所以这种方法不再适用。我也读过这在分片环境中不起作用,虽然这对我来说不是一个问题。
人们似乎有的另一个建议是迭代“from”集合并插入“to”集合。使用正确的WriteConcern(fire and forget),这可能相当快。但它仍然意味着将网络上的每条记录下载到PHP进程中,然后通过网络将其上传回数据库。
我理想地想要一种在服务器端执行此操作的方法。类似于SQL中的INSERT INTO ... SELECT ...这样就可以实现快速,网络效率和PHP的低负载。
答案 0 :(得分:0)
<强>更新强>:
我相信我找到了解决方案。似乎某些版本的PHP驱动程序将对管理数据库进行身份验证,即使它不需要。但是有a workaround其中authSource连接参数用于更改此行为,因此它不会对管理数据库进行身份验证,而是对您选择的数据库进行身份验证。所以现在我的renameCollection函数只是renameCollection命令的包装器。
关键是在连接时添加authSource。在下面的代码中,$ _ENV ['MONGO_URI']保存我的连接字符串,default_database_name()返回我想要认证的数据库的名称。
$class = 'MongoClient';
if( !class_exists($class) ) $class = 'Mongo';
$db_server = new $class($_ENV['MONGO_URI'].'?authSource='.default_database_name());
这是我使用eval的旧版本,虽然某些环境不允许你评估(MongoLab给你一个残缺的设置,除非你有一个专用系统),它也应该有效。但如果你在分片环境中运行,这似乎是一个合理的解决方案。
function renameCollection($old_name, $new_name) {
db()->$new_name->drop();
$copy = "function() {db.$old_name.find().forEach(function(d) {db.$new_name.insert(d)})}";
db()->execute($copy);
db()->$old_name->drop();
}
答案 1 :(得分:0)
我刚试过这个,它按设计工作(http://docs.mongodb.org/manual/reference/command/renameCollection/):
$mongo->admin->command(array('renameCollection'=>'ns.user','to'=>'ns.e'));
这就是你重命名一个未整理的集合的方法。 MR的一个问题是它将改变原始集合的输出形状。因此,它不是很擅长复制集合。如果你的收藏品是分片的,你最好手动复制它。
作为补充说明,我升级到1.4.2(由于某种原因从pecl通道输出到phpinfo()为1.4.3dev :S
),它仍然有效。
答案 2 :(得分:-2)
你可以用它。 “dropTarget”标志为true,然后删除存在的数据库。
$mongo = new MongoClient('_MONGODB_HOST_URL_');
$query = array("renameCollection" => "Database.OldName", "to" => "Database.NewName", "dropTarget" => "true");
$mongo->admin->command($query);