Comment copier une collection d'une base de données à une autre en MongoDB
17 réponses
pour le moment, il n'y a aucun commandement en MongoDB qui ferait cela. Veuillez noter le billet JIRA avec la demande de caractéristique correspondante .
Vous pourriez faire quelque chose comme:
db.<collection_name>.find().forEach(function(d){ db.getSiblingDB('<new_database>')['<collection_name>'].insert(d); });
veuillez noter que les deux bases de données devront partager le même mongod pour que cela fonctionne.
en outre, vous pouvez faire un mongodump d'une collection à partir d'une base de données et puis mongorestore la collection de l'autre base de données.
la meilleure façon est de faire un mongodum puis mongorestore.
vous pouvez sélectionner la collection via:
mongodump -d some_database -c some_collection
[Éventuellement, le code postal du dump ( zip some_database.zip some_database/* -r
) et scp
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 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 ajouter vos index après la copie de vos données. En commençant par 2.4.3, ce processus est automatique, et vous pouvez le désactiver avec --noIndexRestore
.
en fait, il est une commande à déplacer une collection d'une base de données à une autre. Ça ne s'appelle pas "bouger"ou " copier".
pour copier une collection, vous pouvez la cloner sur le même db, puis déplacer le clone.
Pour cloner:
> use db1
> db.source_collection.find().forEach( function(x){db.collection_copy.insert(x)} );
Pour se déplacer:
> 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 mieux pour copier la collection, mais c'est surtout utile si vous cherchez à le déplacer.
je ne l'abus de la fonction de connexion à mongo cli mongo doc . ce qui signifie que vous pouvez démarrer une ou plusieurs connexions. si vous voulez copier la collection de clients de test en test2 dans le même serveur. d'abord vous commencez Mongo shell
use test
var db2 = connect('localhost:27017/test2')
faites une recherche normale et copiez les 20 premiers enregistrements à 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); });
il suffit de changer le localhost en IP ou nom d'hôte pour se connecter au serveur distant. Je l'utilise pour copier des données de test dans une base de données de test pour le test.
si entre deux instances distantes de mongod, utilisez
{ cloneCollection: "<collection>", from: "<hostname>", query: { <query> }, copyIndexes: <true|false> }
voir http://docs.mongodb.org/manual/reference/command/cloneCollection /
je ferais d'habitude:
use sourcedatabase;
var docs=db.sourcetable.find();
use targetdatabase;
docs.forEach(function(doc) { db.targettable.insert(doc); });
je sais qu'il a été répondu à cette question mais je ne répondrais pas personnellement à @JasonMcCays en raison du fait que les curseurs circulent et que cela pourrait causer une boucle de curseur infinie si la collection est encore utilisée. J'utiliserais plutôt un snapshot ():
http://www.mongodb.org/display/DOCS/How+à+faire+Snapshotted+Requêtes+dans+le+Mongo+Base de données
@bens answer est également un bon et fonctionne bien pour les sauvegardes chaudes de collections non seulement cela, mais mongorestore n'a pas besoin de partager la même mongod.
cela pourrait être juste un cas spécial, mais pour une collection de 100k documents avec deux champs de chaîne de caractères aléatoires (la longueur est de 15-20 caractères), en utilisant un muet mapreduce 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 l'agrégation cadre de résoudre votre problème
db.oldCollection.aggregate([{$out : "newCollection"}])
Il shoul noter que les indices 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 = base de données originale
db2 = base de données à copier vers
cursor = db["<collection to copy from>"].find()
for data in cursor:
db2["<new collection>"].insert(data)
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');
il traduit aussi de BSON à JSON, donc mongodump
/ mongorestore
sont la meilleure façon d'aller, comme d'autres l'ont dit.
dans le cas où certains utilisateurs heroku trébucher ici et comme moi veulent copier certaines données de la base de données de mise en scène à la base de données de production ou vice versa voici comment vous le faites très commodément (N.B. j'espère qu'il n'y a pas de fautes de frappe là-dedans, ne peut pas le vérifier atm. Je vais essayer de confirmer la validité du code asap):
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. À partir de v0.8.3 Il y a un outil qui peut le faire en cliquant avec le bouton droit de la souris sur la collection et en sélectionnant "Copier la Collection vers 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é dans 0.8.5 en raison de sa nature buggy donc vous devrez utiliser 0.8.3 ou 0.8.4 si vous voulez l'essayer.
si la RAM n'est pas un problème en utilisant insertMany
est beaucoup plus rapide que forEach
boucle.
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())
Dans mon cas, j'ai dû utiliser un sous-ensemble d'attributs de l'ancienne collection dans 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,
....
})
});`
pour les collections de grande taille, vous pouvez utiliser en vrac.insérer ()
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 copie collection avec 1219 documents: iter vs Bulk (67 secondes vs 3 secondes)