2012-01-19 13 views
45

Chcę sklonować kolekcję MongoDB i zapisać ją na tym samym serwerze pod inną nazwą. Na przykład teraz mam następujące kolekcje: demo1.categories, demo1.users i demo2.users.Sklonuj kolekcję w MongoDB

Chcę mieć "demo2.categories", które jest identyczne z "demo1.categories". (To po prostu ma inną nazwę).

Odpowiedz

76

Jeszcze raz MongoDB documentation comes to the rescue

zakładając, że faktycznie jest kolekcja o nazwie „demo1.categories”:

db.demo1.categories.find().forEach(function(x){db.demo2.categories.insert(x)}); 
+2

słodki, pracował jak talizman! dzięki :) – Daryna

+53

Od wersji 2.1+ możesz zrobić db.demo1.copyTo ("demo2"); –

+12

'copyTo' blokuje wszystkie inne operacje w instancji mongody – r92

2

nie ma już na to polecenie.

Skopiuj jedną kolekcję z jednego serwera na drugi. http://www.mongodb.org/display/DOCS/cloneCollection+Command

+7

Masz rację, że to polecenie pozwoli ci kopiować z jednego serwera na drugi. Jednak pierwotne pytanie dotyczy tego samego serwera. Jak wskazuje dokumentacja, utracisz swoją kolekcję, jeśli spróbujesz użyć komendy cloneCollection dla celu oryginalnego pytania: –

-2

W konsoli mongo można również wykonać następujące czynności, gdzie db_host to komputer, na którym db_host ma bazę danych z kolekcją, którą chcesz sklonować.

użycie db.cloneCollection (,)

+0

Przepraszamy, wystąpiły problemy z formatowaniem, należy użyć db_name, a następnie db.cloneCollection (nazwa_kolekcji, db_host) –

+1

i odwrócić db_host i nazwa kolekcji tj. db.cloneCollection (host, collection) –

+0

która nie działa: {"ok": 0, "errmsg": "nie można klonowaćKolekcja od siebie"} –

28

Najprostszym & skutecznym sposobem jest użycie copyTo(), więc można użyć:

db.source.copyTo("target"); 

& jeśli "target" nie istnieje, to będzie utworzono

- Aktualizacja -

Zgodnie z CopyTo Documentation, ponieważ copyTo() używa wewnętrznie eval, operacje kopiowania będą blokować wszystkie inne operacje na instancji mongod. Dlatego nie powinno się go używać w środowisku produkcyjnym.

- Update -

Ponieważ CopyTo() wykorzystuje eval() wewnętrznie & eval() jest nieaktualna od wersji 3.0, więc CopyTo() jest również przestarzałe od wersji 3.0.

+2

Nie uruchamiaj copyTo w systemie produkcyjnym. Jak wspomniano w komentarzu do zaakceptowanej odpowiedzi, zablokuje ona inne operacje na twojej instancji mongo, skutecznie uniemożliwiając jej działanie na czas. –

+0

@JamesWahlin dziękuję za uwagę, zaktualizowałem odpowiedź, więc każdy może ją łatwo zobaczyć – AbdelHady

+0

'cloneCollectionAsCapped' również blokuje inne operacje. Odkryłem to empirycznie ... – Emer

18

To najszybszy sposób sklonować swoją kolekcję:

mongoexport -d db_name -c src_collection | mongoimport -d db_name -c dst_collection --drop 

będzie klonować src_collection w nazwa_bazy do dst_collection.Czy można to zrobić w dwóch etapach na poziomie bson:

mongodump -d db_name -c src_collection 
mongorestore --drop -d db_name -c dst_collection ./dump/db_name/src_collection.bson 
+2

Naprawdę oszczędzasz mój dzień. To był najłatwiejszy sposób na zrobienie tego: D Dzięki! – cgajardo

+3

Ten sposób jest nie tylko najłatwiejszy, ale gwarantuje także 100% identyczność na poziomie binarnym, ale metoda find() i insert() nie. Na przykład konwertuje wszystkie twoje liczby całkowite na wartości liczbowe, itd. – Tutankhamen

+0

ładne i czyste +1 –

2

Jeśli jesteś zaniepokojony prędkości potem okazało się, że za pomocą aggregate z $project i $out aby być 100 razy szybciej, nie wiem, czy istnieją ograniczenia chociaż, ale trzeba by utworzyć zestaw pól, którą chcesz skopiować na przykład:

// Set of fields in the categories collection var setOfFields = {field1:1, field2:1.......} db.demo1.categories.aggregate([{ "$project": setOfFields},{ $out: "demo2.categories"}]);

tej kopii (projektów) wybrany zestaw pól dla wszystkich dokumentów z demo1.categories do demo2.categories

11

Najszybszym rozwiązaniem jest

db.myoriginal.aggregate([ { $out: "mycopy" } ]) 
+0

Używam https://github.com/caolan/async w mojej aplikacji node.js i to nie działało dla mongodów sterownik node.js - Używam teraz rozwiązania 'find(). forEach (....)' - wciąż jest to przegłosowane, ponieważ działa w konsoli –