PHP的Mongo驱动程序缺少renameCommand函数.有参考通过管理数据库执行此操作.但是,如果没有对该数据库的登录权限,似乎更新版本的Mongo驱动程序不会让您"使用"管理数据库.所以这种方法不再适用.我也读过这在分片环境中不起作用,虽然这对我来说不是一个问题.
人们似乎有的另一个建议是迭代"from"集合并插入"to"集合.使用正确的WriteConcern(fire and forget),这可能相当快.但它仍然意味着将网络上的每条记录下载到PHP进程中,然后通过网络将其上传回数据库.
理想情况下,我希望有一种方法可以在服务器端进行.类似于SQL中的INSERT INTO ... SELECT ... 这样,它具有快速,网络效率和PHP负载低的特点.
更新:
我相信我已经找到了解决方案。看来某些版本的 PHP 驱动程序将针对管理数据库进行身份验证,即使它不需要这样做。但是有一个解决方法,其中 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());
Run Code Online (Sandbox Code Playgroud)
这是我使用 eval 的旧版本,尽管有些环境不允许您进行 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();
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
2239 次 |
最近记录: |