2013-07-22 12 views
7

Sterownik PHP Mongo nie ma funkcji zmiany nazwy. There is reference, aby to zrobić za pośrednictwem administracyjnej bazy danych. Wydaje się jednak, że nowsze wersje sterownika Mongo nie pozwalają na "używanie" administracyjnej bazy danych, jeśli nie mają uprawnień do logowania do tej bazy danych. Tak więc ta metoda już nie działa. Przeczytałem też, że to nie działa w środowisku, w którym występują braki, chociaż obecnie nie jest to dla mnie problemem.Zmiana nazwy kolekcji Mongo w PHP

Inną sugestią, którą ludzie wydają się mieć, jest iteracja poprzez kolekcję "od" i wstawienie jej do kolekcji "do". Przy odpowiednim WriteConcern (ogień i zapomnij) może to być dość szybkie. Ale nadal oznacza to ciągnięcie każdego rekordu przez sieć do procesu PHP, a następnie przesłanie go z powrotem do sieci z powrotem do bazy danych.

Idealnie chcę, aby zrobić to wszystko po stronie serwera. Coś jak INSERT INTO ... SELECT ... w SQL. W ten sposób jest szybki, wydajny w sieci i ma małe obciążenie w PHP.

Odpowiedz

0

Aktualizacje:

  • Usunięto moja stara mapa/zmniejszyć metodę odkąd dowiedział (a Sammaye zauważył), że to zmienia strukturę
  • zrobiłem moją wersję exec wtórnego odkąd dowiedział się, jak zrób to z renameCollection.

Wierzę, że znalazłem rozwiązanie. Wygląda na to, że niektóre wersje sterownika PHP będą uwierzytelniać się przeciwko administracyjnej bazie danych, nawet jeśli nie jest to konieczne. Ale istnieje a workaround, gdzie parametr połączenia authSource jest używany do zmiany tego zachowania, więc nie uwierzytelnia się w administracyjnej bazie danych, lecz w bazie danych wybranej przez użytkownika. Tak więc teraz moja funkcja zmiany nazwy jest po prostu ponownym opakowaniem po komendzie renameCollection.

Kluczem jest dodanie authSource podczas łączenia. W poniższym kodzie $ _ENV ['MONGO_URI'] zawiera mój ciąg połączenia i default_database_name() zwraca nazwę bazy danych, której chcę autoryzować.

$class = 'MongoClient'; 
if(!class_exists($class)) $class = 'Mongo'; 
$db_server = new $class($_ENV['MONGO_URI'].'?authSource='.default_database_name()); 

Oto moja starsza wersja stosowana eval, który powinien również pracować chociaż niektóre środowiska nie pozwalają eval (MongoLab daje chromego konfiguracji, chyba że masz dedykowanego systemu). Ale jeśli pracujesz w zaciemnionym środowisku, wydaje się to rozsądnym rozwiązaniem.

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 zmieni strukturę dokumentu między dwoma zbiorami, i powinieneś być w stanie „wykorzystać” do bazy danych administratora jeśli masz prawo auth – Sammaye

+0

Yea, zdałem sobie sprawę, pisał ten przedwcześnie nie zauważyłem zmiana struktury. Obecnie próbuję dowiedzieć się, jak mogę zrobić mapę/zmniejszyć bez zmniejszenia części. –

+0

Nie ma problemu z redukcją, ale przede wszystkim wewnętrznie, jak MongoDB tworzy wynikowe dokumenty i je zapisuje. W rzeczywistości nigdy nie powinieneś uruchamiać redukcji, ponieważ powinieneś zawsze zwracać tylko jeden klucz na dokument, a MongoDBs nie działa w takim przypadku. – Sammaye

0

właśnie przetestowane, działa zgodnie z przeznaczeniem (http://docs.mongodb.org/manual/reference/command/renameCollection/):

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

W ten sposób można zmienić nazwę unsharded kolekcję. Jednym z problemów z MR jest to, że zmieni kształt wyjścia z oryginalnej kolekcji. Jako taki nie jest zbyt dobry w kopiowaniu kolekcji. Lepiej byłoby skopiować go ręcznie, jeśli twoja kolekcja jest uszkodzona.

Jako dodatkową notatkę uaktualniłem do wersji 1.4.2 (która z jakiegoś powodu wychodzi z kanału pecl do phpinfo() jako 1.4.3dev :S) i nadal działa.

+0

Tak właśnie robiłem. Ale od czasu aktualizacji sterownika mongo (do wersji 1.4.1) przestał działać, narzekając na uwierzytelnianie. Mam jeszcze inną maszynę na starszym sterowniku mongo i działa ona nadal, więc wiem, że to nie jest problem z uprawnieniami do bazy danych. –

+0

@EricAnderson Jestem na 1.4.2 i nie dostaję tego problemu – Sammaye

+0

Może specyficzny dla 1.4.1. Znalazłem problem związany z tym, który zapewnia obejście, używając authSource na https://jira.mongodb.org/browse/PHP-782. Teraz wróć do korzystania tylko z renameCollection. Dzięki za pomoc w zrozumieniu tego wszystkiego. –

-1

możesz tego użyć. Flaga "dropTarget" ma wartość true, a następnie usuń istniejącą bazę danych.

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

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

To nie rozwiązuje problemu. Problem polega na tym, że zmiana nazwy polecenia nie działa zawsze w zależności od poświadczeń i wersji sterownika Mongo. Uruchomienie polecenia z dropTarget było tym, co próbowałem zrobić. Po prostu nie zawsze działa, jeśli nie masz uprawnień w administracyjnej bazie danych lub używasz niektórych wersji sterownika PHP mongo. –