Czy istnieje prosty sposób to zrobić?
Czy istnieje prosty sposób to zrobić?
Odpowiedzi:
W tej chwili nie ma polecenia w MongoDB, które by to zrobiło. Zwróć uwagę na bilet JIRA z powiązanym żądaniem funkcji .
Możesz zrobić coś takiego:
db.<collection_name>.find().forEach(function(d){ db.getSiblingDB('<new_database>')['<collection_name>'].insert(d); });
Zauważ, że dzięki temu dwie bazy danych musiałyby współdzielić tego samego mongod, aby to działało.
Poza tym możesz zrobić mongodump kolekcji z jednej bazy danych, a następnie mongorestore kolekcji w drugiej bazie danych.
Najlepszym sposobem jest zrobienie mongodump, a następnie mongorestore.
Możesz wybrać kolekcję poprzez:
mongodump -d some_database -c some_collection
[Opcjonalnie zip dump ( zip some_database.zip some_database/* -r
) i scp
gdzie indziej]
Następnie przywróć:
mongorestore -d some_other_db -c some_or_other_collection dump/some_collection.bson
Istniejące dane some_or_other_collection
zostaną zachowane. W ten sposób możesz „dołączyć” kolekcję z jednej bazy danych do drugiej.
Przed wersją 2.4.3 trzeba będzie również dodać indeksy po skopiowaniu danych. Począwszy od wersji 2.4.3, proces ten jest automatyczny i można go wyłączyć za pomocą --noIndexRestore
.
Faktycznie, nie jest rozkaz, aby przenieść kolekcję z jednej bazy do drugiej. To po prostu nie nazywa się „przenieś” lub „skopiuj”.
Aby skopiować kolekcję, możesz sklonować ją na tym samym pliku db, a następnie przenieść klon.
Klonować:
> use db1
> db.source_collection.find().forEach( function(x){db.collection_copy.insert(x)} );
Przenieść:
> use admin
switched to db admin
> db.runCommand({renameCollection: 'db1.source_collection', to: 'db2.target_collection'}) // who'd think rename could move?
Inne odpowiedzi są lepsze do kopiowania kolekcji, ale jest to szczególnie przydatne, jeśli chcesz ją przenieść.
'db1.source_collection'
Nadużywam funkcji łączenia w mongo cli mongo doc . oznacza to, że możesz nawiązać jedno lub więcej połączeń. jeśli chcesz skopiować kolekcję klientów z testu na test2 na tym samym serwerze. najpierw zaczniesz mongo shell
use test
var db2 = connect('localhost:27017/test2')
wykonaj normalne wyszukiwanie i skopiuj pierwsze 20 rekordów do testu2.
db.customer.find().limit(20).forEach(function(p) { db2.customer.insert(p); });
lub filtruj według niektórych kryteriów
db.customer.find({"active": 1}).forEach(function(p) { db2.customer.insert(p); });
wystarczy zmienić localhost na IP lub nazwę hosta, aby połączyć się ze zdalnym serwerem. Używam tego do kopiowania danych testowych do testowej bazy danych w celu przetestowania.
Jeśli pomiędzy dwoma zdalnymi instancjami mongod, użyj
{ cloneCollection: "<collection>", from: "<hostname>", query: { <query> }, copyIndexes: <true|false> }
Zobacz http://docs.mongodb.org/manual/reference/command/cloneCollection/
copyIndexes
opcji faktycznie nie jest przestrzegane. Indeksy są zawsze kopiowane. Patrz SERWER-11418
dla kolekcji o dużych rozmiarach można użyć Bulk.insert ()
var bulk = db.getSiblingDB(dbName)[targetCollectionName].initializeUnorderedBulkOp();
db.getCollection(sourceCollectionName).find().forEach(function (d) {
bulk.insert(d);
});
bulk.execute();
Zaoszczędzi to dużo czasu . W moim przypadku kopiuję kolekcję z 1219 dokumentami: iter vs Bulk (67 sekund vs 3 sekundy)
Możesz użyć struktury agregacji, aby rozwiązać problem
db.oldCollection.aggregate([{$out : "newCollection"}])
Należy zauważyć, że indeksy z oldCollection nie będą kopiowane w newCollection.
Wiem, że na to pytanie udzielono odpowiedzi, ale ja osobiście nie odpowiedziałbym na @JasonMcCays z powodu faktu, że kursory przesyłają strumieniowo, co może powodować nieskończoną pętlę kursora, jeśli kolekcja jest nadal używana. Zamiast tego użyłbym snapshot ():
http://www.mongodb.org/display/DOCS/How+to+do+Snapshotted+Queries+in+the+Mongo+Database
Odpowiedź @bens jest również dobra i działa dobrze na gorące kopie zapasowe kolekcji nie tylko to, ale sklep mongorestore nie musi dzielić tego samego mongod.
Może to być tylko szczególny przypadek, ale w przypadku zbioru 100 000 dokumentów z dwoma losowymi polami ciągów (długość wynosi 15-20 znaków) użycie głupej redukcji map jest prawie dwa razy szybsze niż znajdowanie-wstawianie / kopiowanie
db.coll.mapReduce(function() { emit(this._id, this); }, function(k,vs) { return vs[0]; }, { out : "coll2" })
Używając pymongo, musisz mieć obie bazy danych na tym samym mongod, zrobiłem następujące:
db = oryginalna baza danych
db2 = baza danych do skopiowania
cursor = db["<collection to copy from>"].find()
for data in cursor:
db2["<new collection>"].insert(data)
To nie rozwiąże twojego problemu, ale powłoka mongodb ma copyTo
metodę, która kopiuje kolekcję do innej w tej samej bazie danych :
db.mycoll.copyTo('my_other_collection');
To także tłumaczy z BSON na JSON, więc mongodump
/ mongorestore
są najlepszą drogą, jak mówili inni.
Jeśli pamięć RAM nie stanowi problemu, użycie insertMany
jest znacznie szybsze niż forEach
pętla.
var db1 = connect('<ip_1>:<port_1>/<db_name_1>')
var db2 = connect('<ip_2>:<port_2>/<db_name_2>')
var _list = db1.getCollection('collection_to_copy_from').find({})
db2.collection_to_copy_to.insertMany(_list.toArray())
W przypadku, gdy niektórzy użytkownicy Heroku natkną się tutaj i tak jak ja chcą skopiować niektóre dane z bazy pomostowej do produkcyjnej bazy danych lub odwrotnie, oto jak to zrobić bardzo wygodnie (NB Mam nadzieję, że nie ma tam literówek, nie mogę sprawdzić bankomatu., Spróbuję potwierdzić poprawność kodu jak najszybciej):
to_app="The name of the app you want to migrate data to"
from_app="The name of the app you want to migrate data from"
collection="the collection you want to copy"
mongohq_url=`heroku config:get --app "$to_app" MONGOHQ_URL`
parts=(`echo $mongohq_url | sed "s_mongodb://heroku:__" | sed "s_[@/]_ _g"`)
to_token=${parts[0]}; to_url=${parts[1]}; to_db=${parts[2]}
mongohq_url=`heroku config:get --app "$from_app" MONGOHQ_URL`
parts=(`echo $mongohq_url | sed "s_mongodb://heroku:__" | sed "s_[@/]_ _g"`)
from_token=${parts[0]}; from_url=${parts[1]}; from_db=${parts[2]}
mongodump -h "$from_url" -u heroku -d "$from_db" -p"$from_token" -c "$collection" -o col_dump
mongorestore -h "$prod_url" -u heroku -d "$to_app" -p"$to_token" --dir col_dump/"$col_dump"/$collection".bson -c "$collection"
Zawsze możesz użyć Robomongo. Od wersji 0.8.3 istnieje narzędzie, które może to zrobić, klikając kolekcję prawym przyciskiem myszy i wybierając polecenie „Kopiuj kolekcję do bazy danych”
Aby uzyskać szczegółowe informacje, zobacz http://blog.robomongo.org/whats-new-in-robomongo-0-8-3/
Ta funkcja została usunięta w wersji 0.8.5 ze względu na jej wadliwy charakter, więc będziesz musiał użyć wersji 0.8.3 lub 0.8.4, jeśli chcesz ją wypróbować.
W moim przypadku musiałem użyć podzbioru atrybutów ze starej kolekcji w mojej nowej kolekcji. Wybrałem więc te atrybuty, wywołując insert w nowej kolekcji.
db.<sourceColl>.find().forEach(function(doc) {
db.<newColl>.insert({
"new_field1":doc.field1,
"new_field2":doc.field2,
....
})
});`
użyj „Studio3T for MongoDB”, które mają narzędzia do eksportowania i importowania, klikając bazę danych, kolekcje lub link do pobrania konkretnej kolekcji: https://studio3t.com/download/
Można to zrobić za pomocą db.copyDatabase
metody Mongo :
db.copyDatabase(fromdb, todb, fromhost, username, password)
Odniesienie: http://docs.mongodb.org/manual/reference/method/db.copyDatabase/