2013-07-22 18 views
7

PHPのMongoドライバにはrenameCommand関数がありません。 There is referenceこれは管理データベースを介して行います。しかし、最近のバージョンのMongoドライバは、そのデータベースに対するログイン権限を持っていなければ、単に管理データベースを "使用"することはできません。したがって、この方法はもはや機能しません。私はまた、これは私にとっては現在懸念されていませんが、シャード環境では動作しないことも読んでいます。PHPでMongoコレクションの名前を変更

人々が持っていると思われる他の提案は、「from」コレクションを繰り返して「to」コレクションに挿入することです。適切なWriteConcern(fireとforget)を使用すると、これはかなり高速になる可能性があります。しかし、それは、ネットワーク上の各レコードをPHPプロセスにプルダウンした後、ネットワーク上にアップロードしてデータベースに戻すことを意味します。

私は理想的にはすべてのサーバー側でそれを行う方法が欲しいです。 SQLのINSERT INTO ... SELECT ...のような並べ替え。これにより、高速でネットワーク効率がよく、PHPに負荷がかかりません。

答えて

0

アップデート

  • 削除私の古いマップ/私が見つけた(とSammayeが指摘)ので、これは私がどのように見つけたので、
  • は二次私のexecのバージョンを作った構造を変えるという方法を削減それをrenameCollectionで行います。

私は解決策を見つけたと信じています。 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()); 

は、一部の環境では(あなたは、専用のシステムを持っていない限り、MongoLabはあなたに不自由セットアップを与える)あなたはevalにはできませんがも動作するはずのevalを使用し、私の古いバージョンです。しかし、シャード環境で実行している場合、これは合理的な解決策のようです。 (http://docs.mongodb.org/manual/reference/command/renameCollection/)設計どおりに私はこれをテストしている

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(); 
} 
+0

MRは、2つの収集の間の文書の構造を変更します、とあなたは右の認証 – Sammaye

+0

いやを持っている場合、管理データベースを「使用」することができるはず、私は気付かなかったとして、私は途中でこの投稿を実現しました構造が変化する。私は現在、削減部分なしでマップ/リダクションをどのように行うことができるかを把握しようとしています。 –

+0

MongoDBが結果として得られる文書をどのように作成して書き出すのかは、基本的には削減されているが、内部的には問題ではありません。実際には、ドキュメントごとに1つのキーだけを返すべきであり、MongoDBsの削減はそのようなケースでは実行されないので、reduceを実行するべきではありません。 – Sammaye

0

は、それが動作します:あなたがunshardedコレクションの名前を変更する方法

$mongo->admin->command(array('renameCollection'=>'ns.user','to'=>'ns.e')); 

であること。 MRの1つの問題は、元のコレクションからの出力の形状を変更することです。このように、コレクションをコピーすることはあまりよくありません。コレクションが断片化されている場合は、手動でコピーする方がよいでしょう。

私は1.4.2にアップグレードしました。何らかの理由でpeclチャネルからphpinfo()に1.4.3dev :Sという名前が付けられていますが、それでも動作します。

+0

これは私がしたことです。しかし、私はmongoドライバを1.4.1にアップグレードして以来、認証に関して不平を言っていました。私は古いmongoドライバ上にまだ別のマシンを持っており、それはまだ動作しているので、データベースのアクセス権の問題ではないことが分かります。 –

+0

@EricAnderson私は1.4.2を使っていますが、その問題は発生しません。 – Sammaye

+0

多分1.4.1に固有です。私はhttps://jira.mongodb.org/browse/PHP-782でauthSourceを使って回避策を提供する問題を発見しました。さあ、今度はrenameCollectionを使ってみましょう。これをすべて理解するのを助けてくれてありがとう。 –

-1

これは使用できます。 "dropTarget"フラグがtrueの場合、データベースは削除されます。

$mongo = new MongoClient('_MONGODB_HOST_URL_'); 
    $query = array("renameCollection" => "Database.OldName", "to" => "Database.NewName", "dropTarget" => "true"); 

    $mongo->admin->command($query); 
+0

これは問題を解決しません。問題は、renameCommandが資格情報とMongoドライバのバージョンによっては常に動作しないことです。 dropTargetでコマンドを実行することは、私がやろうとしていたことでした。管理データベースに関する特権を持たないか、特定のバージョンのPHP mongoドライバを使用している場合には、常に機能するとは限りません。 –

関連する問題