C'è un modo semplice per fare questo?
C'è un modo semplice per fare questo?
Risposte:
Al momento non esiste alcun comando in MongoDB che lo farebbe. Si prega di notare il biglietto JIRA con relativa richiesta di funzionalità .
Potresti fare qualcosa del tipo:
db.<collection_name>.find().forEach(function(d){ db.getSiblingDB('<new_database>')['<collection_name>'].insert(d); });
Si noti che con questo, i due database dovrebbero condividere lo stesso mongod per farlo funzionare.
Oltre a ciò, è possibile eseguire una mongodump di una raccolta da un database e quindi salvare la raccolta nell'altro database.
Il modo migliore è fare una mongodump e poi una mongorestore.
È possibile selezionare la raccolta tramite:
mongodump -d some_database -c some_collection
[Facoltativamente, comprimi il dump ( zip some_database.zip some_database/* -r
) e scp
altrove]
Quindi ripristinalo:
mongorestore -d some_other_db -c some_or_other_collection dump/some_collection.bson
I dati esistenti some_or_other_collection
verranno conservati. In questo modo è possibile "aggiungere" una raccolta da un database a un altro.
Prima della versione 2.4.3, sarà necessario aggiungere nuovamente gli indici dopo aver copiato i dati. A partire dalla 2.4.3, questo processo è automatico e puoi disabilitarlo con --noIndexRestore
.
In realtà, c'è un comando per spostare una raccolta da un database a un altro. Non si chiama semplicemente "sposta" o "copia".
Per copiare una raccolta, puoi clonarla sullo stesso db, quindi spostare il clone.
Per clonare:
> use db1
> db.source_collection.find().forEach( function(x){db.collection_copy.insert(x)} );
Spostare:
> use admin
switched to db admin
> db.runCommand({renameCollection: 'db1.source_collection', to: 'db2.target_collection'}) // who'd think rename could move?
Le altre risposte sono migliori per copiare la raccolta, ma ciò è particolarmente utile se stai cercando di spostarla.
'db1.source_collection'
Vorrei abusare della funzione di connessione in mongo cli mongo doc . quindi ciò significa che è possibile avviare una o più connessioni. se si desidera copiare la raccolta clienti da test a test2 nello stesso server. per prima cosa inizi a mongo shell
use test
var db2 = connect('localhost:27017/test2')
fare una ricerca normale e copiare i primi 20 record in test2.
db.customer.find().limit(20).forEach(function(p) { db2.customer.insert(p); });
o filtrare in base ad alcuni criteri
db.customer.find({"active": 1}).forEach(function(p) { db2.customer.insert(p); });
basta cambiare localhost in IP o nome host per connettersi al server remoto. Lo uso per copiare i dati di test in un database di test per i test.
Se tra due istanze mongod remote, utilizzare
{ cloneCollection: "<collection>", from: "<hostname>", query: { <query> }, copyIndexes: <true|false> }
Vedi http://docs.mongodb.org/manual/reference/command/cloneCollection/
copyIndexes
campo delle opzioni in realtà non è rispettato. Gli indici vengono sempre copiati. Vedi SERVER-11418
per raccolte di grandi dimensioni, puoi usare Bulk.insert ()
var bulk = db.getSiblingDB(dbName)[targetCollectionName].initializeUnorderedBulkOp();
db.getCollection(sourceCollectionName).find().forEach(function (d) {
bulk.insert(d);
});
bulk.execute();
Ciò farà risparmiare molto tempo . Nel mio caso, sto copiando la raccolta con 1219 documenti: iter vs Bulk (67 secondi contro 3 secondi)
È possibile utilizzare il framework di aggregazione per risolvere il problema
db.oldCollection.aggregate([{$out : "newCollection"}])
Va notato che gli indici di oldCollection non verranno copiati in newCollection.
So che a questa domanda è stata data una risposta, ma personalmente non risponderei @JasonMcCays a causa del fatto che il flusso di cursori e questo potrebbe causare un ciclo di cursore infinito se la raccolta è ancora in uso. Invece vorrei usare uno snapshot ():
http://www.mongodb.org/display/DOCS/How+to+do+Snapshotted+Queries+in+the+Mongo+Database
Anche la risposta @bens è buona e funziona bene per i backup a caldo delle raccolte non solo, ma mongorestore non ha bisogno di condividere lo stesso mongod.
Questo potrebbe essere solo un caso speciale, ma per una raccolta di 100.000 documenti con due campi di stringa casuali (la lunghezza è di 15-20 caratteri), l'utilizzo di un mapreduce muto è quasi due volte più veloce di find-insert / copy.
db.coll.mapReduce(function() { emit(this._id, this); }, function(k,vs) { return vs[0]; }, { out : "coll2" })
Usando pymongo, devi avere entrambi i database sullo stesso mongod, ho fatto quanto segue:
db = database originale
db2 = database da copiare
cursor = db["<collection to copy from>"].find()
for data in cursor:
db2["<new collection>"].insert(data)
Questo non risolverà il tuo problema ma la shell mongodb ha un copyTo
metodo che copia una collezione in un'altra nello stesso database :
db.mycoll.copyTo('my_other_collection');
Si traduce anche da BSON a JSON, quindi mongodump
/ mongorestore
sono il modo migliore per andare, come altri hanno già detto.
Se la RAM non è un problema, l'utilizzo insertMany
è molto più veloce del forEach
loop.
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())
Nel caso in cui alcuni utenti di heroku si imbattessero qui e come me volessero copiare alcuni dati dal database di staging al database di produzione o viceversa ecco come lo fai in modo molto conveniente (NB Spero che non ci siano errori di battitura lì dentro, non riesco a controllarli., Proverò a confermare la validità del codice al più presto):
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"
Puoi sempre usare Robomongo. A partire dalla v0.8.3 esiste uno strumento che può farlo facendo clic con il tasto destro del mouse sulla raccolta e selezionando "Copia raccolta nel database"
Per i dettagli, consultare http://blog.robomongo.org/whats-new-in-robomongo-0-8-3/
Questa funzione è stata rimossa in 0.8.5 a causa della sua natura buggy, quindi dovrai usare 0.8.3 o 0.8.4 se vuoi provarlo.
Nel mio caso, ho dovuto utilizzare un sottoinsieme di attributi della vecchia raccolta nella mia nuova raccolta. Così ho finito per scegliere quegli attributi mentre chiamavo insert sulla nuova collezione.
db.<sourceColl>.find().forEach(function(doc) {
db.<newColl>.insert({
"new_field1":doc.field1,
"new_field2":doc.field2,
....
})
});`
usa "Studio3T per MongoDB" che dispone di strumenti di esportazione e importazione facendo clic su database, raccolte o link per il download di raccolte specifiche: https://studio3t.com/download/
Questo può essere fatto usando il db.copyDatabase
metodo Mongo :
db.copyDatabase(fromdb, todb, fromhost, username, password)
Riferimento: http://docs.mongodb.org/manual/reference/method/db.copyDatabase/