Comment copier une collection d’une firebase database à une autre dans MongoDB

Existe-t-il un moyen simple de le faire?

Pour le moment, il n’y a pas de commande dans MongoDB qui le ferait. Veuillez noter le ticket JIRA avec demande de fonctionnalité associée .

Vous pourriez faire quelque chose comme:

db..find().forEach(function(d){ db.getSiblingDB('')[''].insert(d); }); 

Veuillez noter qu’avec cela, les deux bases de données devront partager le même modèle pour que cela fonctionne.

En plus de cela, vous pouvez faire un mongodump d’une collection à partir d’une firebase database et ensuite stocker la collection dans l’autre firebase database.

Le meilleur moyen est de faire un mongodump puis un mongorestore.

Vous pouvez sélectionner la collection via:

 mongodump -d some_database -c some_collection 

[Facultativement, compressez le dump ( zip some_database.zip some_database/* -r ) et scp le ailleurs]

Puis le restaurer:

 mongorestore -d some_other_db -c some_or_other_collection dump/some_collection.bson 

Les données existantes dans some_or_other_collection seront conservées. De cette façon, vous pouvez “append” une collection d’une firebase database à une autre.

Avant la version 2.4.3, vous devrez également append vos index après avoir copié vos données. À partir de 2.4.3, ce processus est automatique et vous pouvez le désactiver avec --noIndexRestore .

En fait, il existe une commande pour déplacer une collection d’une firebase database à une autre. Ce n’est simplement pas appelé “déplacer” ou “copier”.

Pour copier une collection, vous pouvez la cloner sur la même firebase database, puis déplacer le clone.

Cloner:

 > use db1 > db.source_collection.find().forEach( function(x){db.collection_copy.insert(x)} ); 

Bouger:

 > use admin switched to db admin > db.runCommand({renameCollection: 'db1.source_collection', to: 'db2.target_collection'}) // who'd think rename could move? 

Les autres réponses sont meilleures pour copier la collection, mais cela est particulièrement utile si vous souhaitez le déplacer.

J’abuserais de la fonction de connexion dans mongo cli mongo doc . cela signifie que vous pouvez démarrer une ou plusieurs connexions. Si vous souhaitez copier la collecte de clients du test vers test2 sur le même serveur. d’abord vous commencez mongo shell

 use test var db2 = connect('localhost:27017/test2') 

faire une recherche normale et copier les 20 premiers enregistrements à tester2.

 db.customer.find().limit(20).forEach(function(p) { db2.customer.insert(p); }); 

ou filtrer par certains critères

 db.customer.find({"active": 1}).forEach(function(p) { db2.customer.insert(p); }); 

changez simplement le localhost en IP ou hostname pour vous connecter au serveur distant. Je l’utilise pour copier des données de test dans une firebase database de test pour les tester.

Si entre deux instances distantes de mongod, utilisez

 { cloneCollection: "", from: "", query: {  }, copyIndexes:  } 

Voir http://docs.mongodb.org/manual/reference/command/cloneCollection/

Je le faisais habituellement:

 use sourcedatabase; var docs=db.sourcetable.find(); use targetdatabase; docs.forEach(function(doc) { db.targettable.insert(doc); }); 

Je sais que cette question a été résolue, mais personnellement, je ne ferais pas de réponse @JasonMcCays en raison du fait que les curseurs sont diffusés, ce qui pourrait provoquer une boucle de curseur infinie si la collection est toujours utilisée. Au lieu de cela, j’utiliserais un instantané ():

http://www.mongodb.org/display/DOCS/How+to+do+Snapshotted+Queries+in+the+Mongo+Database

La réponse de @bens est également bonne et fonctionne bien pour les sauvegardes à chaud des collections, mais mongorestore n’a pas besoin de partager le même mongod.

Cela peut être juste un cas particulier, mais pour une collection de 100 000 documents avec deux champs de chaînes aléatoires (la longueur est de 15 à 20 caractères), utiliser un mapreduce muet est presque deux fois plus rapide que find-insert / copyTo:

 db.coll.mapReduce(function() { emit(this._id, this); }, function(k,vs) { return vs[0]; }, { out : "coll2" }) 

Vous pouvez utiliser la structure d’agrégation pour résoudre votre problème

 db.oldCollection.aggregate([{$out : "newCollection"}]) 

Il faut noter que les index de oldCollection ne seront pas copiés dans newCollection.

En utilisant pymongo, vous devez avoir les deux bases de données sur le même mongod, j’ai fait ce qui suit:


db = firebase database originale
db2 = firebase database à copier

 cursor = db[""].find() for data in cursor: db2[""].insert(data) 

Cela ne résoudra pas votre problème mais le shell copyTo a une méthode copyTo qui copie une collection dans une autre dans la même firebase database :

 db.mycoll.copyTo('my_other_collection'); 

Cela se traduit aussi de BSON à JSON, donc mongodump / mongorestore est la meilleure solution, comme d’autres l’ont déjà dit.

Au cas où certains utilisateurs d’Heroku trébucheraient ici et comme moi, ils veulent copier certaines données de la firebase database intermédiaire dans la firebase database de production ou vice versa, voici comment vous le faites très facilement. Je vais essayer de confirmer la validité du code dès que possible):

 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" 

Cela peut être fait en utilisant la méthode db.copyDatabase de Mongo:

 db.copyDatabase(fromdb, todb, fromhost, username, password) 

Référence: http://docs.mongodb.org/manual/reference/method/db.copyDatabase/

Vous pouvez toujours utiliser Robomongo. A partir de la v0.8.3, il existe un outil permettant de le faire en cliquant avec le bouton droit sur la collection et en sélectionnant “Copier la collection dans la firebase database”.

Pour plus de détails, voir http://blog.robomongo.org/whats-new-in-robomongo-0-8-3/

Cette fonctionnalité a été supprimée en 0.8.5 en raison de sa nature boguée, vous devrez donc utiliser 0.8.3 ou 0.8.4 si vous voulez l’essayer.

Si la RAM n’est pas un problème, l’utilisation de insertMany est beaucoup plus rapide que la boucle forEach .

 var db1 = connect(':/') var db2 = connect(':/') var _list = db1.getCollection('collection_to_copy_from').find({}) db2.collection_to_copy_to.insertMany(_list.toArray()) 

Dans mon cas, j’ai dû utiliser un sous-ensemble d’atsortingbuts de l’ancienne collection dans ma nouvelle collection. J’ai donc fini par choisir ces atsortingbuts en appelant insert sur la nouvelle collection.

 db..find().forEach(function(doc) { db..insert({ "new_field1":doc.field1, "new_field2":doc.field2, .... }) });` 

pour les collections de grande taille, vous pouvez utiliser Bulk.insert ()

 var bulk = db.getSiblingDB(dbName)[targetCollectionName].initializeUnorderedBulkOp(); db.getCollection(sourceCollectionName).find().forEach(function (d) { bulk.insert(d); }); bulk.execute(); 

Cela permettra d’économiser beaucoup de temps . Dans mon cas, je recopie la collection avec 1219 documents: iter vs Bulk (67 secs vs 3 secs)