web-dev-qa-db-fra.com

Comment copier une collection d'une base de données vers une autre dans MongoDB

Y a-t-il un moyen simple de faire cela?

190
EasonBlack

Pour le moment, aucune commande dans MongoDB ne le ferait. Veuillez noter le billet JIRA avec demande de fonctionnalité connexe .

Vous pourriez faire quelque chose comme:

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

Veuillez noter qu'avec cela, les deux bases de données devraient partager le même mongod pour que cela fonctionne. 

En plus de cela, vous pouvez faire un mongodump d'une collection à partir d'une base de données, puis la restaurer dans la base de données.

172
Jason McCay

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

[Facultatif, décompressez le dump (Zip some_database.Zip some_database/* -r) et le scp ailleurs]

Puis restaurez-le:

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

Les données existantes dans some_or_other_collection seront préservées. De cette façon, vous pouvez "ajouter" une collection d'une base de données à une autre.

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

256
Ben

En fait, il y a une commande pour déplacer une collection d'une base de données à une autre. Ce n'est simplement pas appelé "déplacer" ou "copier".

Pour copier une collection, vous pouvez la cloner sur la même base de données, 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 la déplacer.

76
Anuj Gupta

J'abuserais de la fonction de connexion dans mongo cli mongo doc . cela signifie donc que vous pouvez démarrer une ou plusieurs connexions . si vous souhaitez copier la collection de clients de test à test2 sur le même serveur. D'abord, vous commencez Shell Shell

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

effectuez une recherche normale et copiez les 20 premiers enregistrements dans test2.

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

ou filtrer selon certains critères

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

changez simplement l’hôte local en IP ou nom d’hôte pour vous connecter au serveur distant. J'utilise ceci pour copier des données de test dans une base de données de test à des fins de test.

22
wayne

Si entre deux instances de mongod distantes, utilisez 

{ cloneCollection: "<collection>", from: "<hostname>", query: { <query> }, copyIndexes: <true|false> } 

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

18
es cologne

Je ferais habituellement:

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

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

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

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

5
Alexander Makarov

Je sais que cette question a reçu une réponse, mais personnellement, je ne ferais pas de réponse à @JasonMcCays en raison du flux de curseurs, ce qui pourrait entraîner une boucle de curseur infinie si la collection est toujours utilisée. Au lieu de cela, je voudrais utiliser un instantané ():

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

@bens answer est également un bon choix et fonctionne bien pour les sauvegardes à chaud des collections non seulement, mais mongorestore n’a pas besoin de partager le même mongod.

5
Sammaye

Ce n'est peut-être qu'un cas spécial, mais pour une collection de 100 000 documents comportant deux champs de chaîne aléatoires (la longueur est de 15 à 20 caractères), l'utilisation d'une mapreduce muette est presque deux fois plus rapide que celle de find-insert/copyTo:

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

Avec pymongo, vous devez avoir les deux bases de données sur le même mongod.


db = base de données d'origine
db2 = base de données à copier

cursor = db["<collection to copy from>"].find()
for data in cursor:
    db2["<new collection>"].insert(data)
4
vbhakta

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 économisera beaucoup de temps. Dans mon cas, je copie une collection de 1219 documents: iter vs Bulk (67 s vs 3 s)

3
nametal

Si RAM n’est pas un problème, utiliser insertMany est bien plus rapide que la boucle forEach

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())
2
TheNeverLander

Cela ne résoudra pas votre problème mais le shell mongodb a une méthode copyTo qui copie une collection dans une autre dans la même base de données:

db.mycoll.copyTo('my_other_collection');

Cela se traduit également de BSON à JSON, donc mongodump/mongorestore est la meilleure voie à suivre, comme l'ont déjà dit d'autres.

2
Roberto

Vous pouvez toujours utiliser Robomongo. À partir de la version 0.8.3, un outil peut le faire en cliquant avec le bouton droit sur la collection et en sélectionnant "Copier la collection dans la base de données".

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

Cette fonctionnalité a été supprimée dans 0.8.5 en raison de son caractère buggy, vous devrez donc utiliser 0.8.3 ou 0.8.4 si vous voulez l'essayer.

1
dross

Au cas où certains utilisateurs de heroku trébucheraient ici et voudraient, comme moi, copier des données de la base de données intermédiaire dans la base de données de production ou inversement, voici comment vous pouvez le faire très facilement (NB: j'espère qu'il n'y a pas de fautes de frappe, je ne peux pas le vérifier, 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"
1
Timo

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

db.<sourceColl>.find().forEach(function(doc) { 
    db.<newColl>.insert({
        "new_field1":doc.field1,
        "new_field2":doc.field2,
        ....
    })
});`
0
dranga

utilisez "Studio3T pour MongoDB" qui ont des outils d'exportation et d'importation en cliquant sur la base de données, les collections ou une collection spécifique lien de téléchargement: https://studio3t.com/download/

0
A.Hamzavi

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/

0
nnamdi