2013-07-22 2 views
7

PHP의 Mongo 드라이버에는 renameCommand 함수가 없습니다. There is reference은 admin 데이터베이스를 통해이를 수행합니다. 그러나 최근 버전의 Mongo 드라이버는 해당 데이터베이스에 대한 로그인 권한이없는 경우 관리 데이터베이스를 "사용"하지 않습니다. 따라서이 방법은 더 이상 작동하지 않습니다. 나는 이것이 현재 나를 걱정하지 않지만 샤르드 환경에서는 작동하지 않는다는 것도 읽었습니다.PHP에서 몽고 컬렉션 이름 바꾸기

다른 사람들은 "from"컬렉션을 반복하고 "to"컬렉션에 삽입해야한다고 생각합니다. 적절한 WriteConcern (fire and forget)을 사용하면 상당히 빠를 수 있습니다. 그러나 여전히 네트워크를 통해 각 레코드를 PHP 프로세스로 끌어온 다음 다시 네트워크를 통해 데이터베이스로 다시 업로드하는 것을 의미합니다.

나는 모든 서버 쪽에서 그것을하는 것이 가장 이상적이다. SQL에서 INSERT INTO ... SELECT ...와 같은 정렬. 이 방법은 빠르고 네트워크 효율이 높으며 PHP에 대한 부하가 적습니다.

답변

0

업데이트 :

  • 제거 내 옛지도/내가 발견 (그리고 Sammaye 지적) 이후이 내가 방법을 발견 이후
  • 보조 내 간부 버전을 제작 구조를 변경하는 것이 방법을 감소 renameCollection으로 처리하십시오.

나는 해결책을 찾았다 고 생각합니다. PHP 드라이버의 일부 버전은 필요하지 않더라도 admin 데이터베이스에 대해 인증 할 것입니다. 그러나 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 당신에게 불구 설정을 제공합니다) 사용 내 이전 버전입니다. 그러나 당신이 sharded 환경에서 달리는 경우에 이것은 적당한 해결책 같이 보인다. (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 두 모음 사이의 문서 구조를 변경됩니다, 당신은 당신이 올바른 인증을 – Sammaye

+0

네이있는 경우 관리자 데이터베이스를 "사용"할 수 있어야한다, 나는 내가 알아 차리지 않았다으로 조기에이 게시 실현 구조가 바뀐다. 나는 현재지도/축소 작업을 할 수있는 방법을 알아 내려고 노력하고 있습니다. –

+0

MongoDB가 결과 문서를 작성하고 작성하는 방법은 근본적으로는 줄이긴하지만 내부적으로는 문제가되지 않습니다. 사실 문서 당 하나의 키만 반환해야하므로 MongoDBs reduce는이 경우 실행되지 않습니다. – Sammaye

0

, 그것은 작동합니다 : 당신이 unsharded 모음의 이름을 변경하는 방법

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

즉. MR의 한 가지 문제점은 원본 컬렉션의 출력 모양이 변경된다는 것입니다. 따라서 컬렉션을 복사하는 것은 그리 좋지 않습니다. 컬렉션이 조각으로 나뉘어지면 수동으로 복사하는 것이 좋습니다.

내가 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 특정. authSource를 사용하여 https://jira.mongodb.org/browse/PHP-782에서 해결 방법을 제공하는 것과 관련된 문제를 발견했습니다. 이제 다시 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으로 명령을 실행하는 것은 내가하려는 일이었습니다. admin 데이터베이스에 대한 권한이 없거나 특정 버전의 PHP mongo 드라이버를 사용하고있는 경우에는 항상 작동하지 않습니다. –