MongoDB में एक डेटाबेस से दूसरे में एक संग्रह की प्रतिलिपि कैसे करें


221

क्या ऐसा करने के लिए एक सरल तरीका है?


40
स्वीकृत उत्तर यकीनन 2012 में सबसे अच्छा तरीका था, लेकिन अब db.cloneCollection () अक्सर एक बेहतर समाधान है। यहाँ हाल ही में कुछ और उत्तर दिए गए हैं, जो इसका संदर्भ देते हैं, इसलिए यदि आप Google से आए (जैसे मैंने किया) तो सभी उत्तरों पर एक नज़र डालें!
केल्विन

4
अन्य उत्तरों को पढ़ने के साथ-साथ यह सुनिश्चित करने के लिए भी सुनिश्चित करें कि यह आपकी आवश्यकताओं पर फिट बैठता है, न कि केवल उसकी स्थिति में @kelvin की
PW Kad

जवाबों:


206

फिलहाल MongoDB में कोई आदेश नहीं है जो ऐसा करेगा। कृपया संबंधित सुविधा अनुरोध के साथ JIRA टिकट पर ध्यान दें ।

आप कुछ ऐसा कर सकते हैं:

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

कृपया ध्यान दें कि इसके साथ, दो डेटाबेस को काम करने के लिए एक ही मोंगॉड को साझा करना होगा।

इसके अलावा, आप एक डेटाबेस से एक संग्रह का एक mongodump कर सकते हैं और फिर संग्रह को दूसरे डेटाबेस में mongorestore कर सकते हैं।


13
ध्यान दें कि यदि आप जेएस शेल में कॉपी करते हैं तो प्रक्रिया के दौरान BSON दस्तावेज़ JSON में डिकोड हो जाते हैं इसलिए कुछ दस्तावेज़ प्रकार में परिवर्तन कर सकते हैं। आम तौर पर बेहतर दृष्टिकोण हैं।
स्टेनी जूल

1
माना। यह शेल के साथ आसपास रहने के लिए सिर्फ एक मजेदार सुझाव था। इसके अलावा, यह इंडेक्स पर नहीं लाएगा। अगर मैं ऐसा कर रहा था, तो मैं हर बार मोंगोडंप / मोंगोरेस्टोर करूंगा।
जेसन मैकके जूल

2
धन्यवाद। कृपया ध्यान दें कि आपके पास कोड में एक टाइपो है, न कि getSiblingDB फ़ंक्शन को बंद करना। यहाँ सही कोड है: db। <Collection_name> .find ()। ForEach (फ़ंक्शन (d) {db.getSiblingDB ('<new_database>') [] <collection_name> ']। Insert (d);});
फ्लेविउ

1
इसने टेस्ट रनों के बीच एक गोल्डन कॉपी से एक टेस्ट मोंगोडब को रीसेट करने के लिए अच्छी तरह से काम किया। संग्रह के नामों की हार्ड कोडिंग के बजाय आप उन सभी संग्रह नामों पर लूप के लिए कर सकते हैं जिन्हें आप db.getCollection (नाम) .find () के साथ कॉपी करना चाहते हैं। forbach और एक फ़ंक्शन जो db.getSiblingDB ("otherdb") की आपूर्ति करता है। getCollection (नाम) .Insert (घ)।
simbo1905

2
क्या यह विशाल आकार के संग्रह के लिए कुशल है?
खलील अवदा

284

सबसे अच्छा तरीका है कि एक मोंगोडंप फिर मोंगोरेस्टोर करें।

आप के माध्यम से संग्रह का चयन कर सकते हैं:

mongodump -d some_database -c some_collection

[वैकल्पिक रूप से, डंप ज़िप करें ( zip some_database.zip some_database/* -r) और scpयह कहीं और]

फिर इसे पुनर्स्थापित करें:

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

मौजूदा डेटा some_or_other_collectionसंरक्षित किया जाएगा। इस तरह आप एक डेटाबेस से दूसरे में एक संग्रह "जोड़" सकते हैं।

संस्करण 2.4.3 से पहले, आपको अपने डेटा पर कॉपी करने के बाद अपने अनुक्रमित को वापस जोड़ना होगा। 2.4.3 से शुरू होकर, यह प्रक्रिया स्वचालित है, और आप इसे अक्षम कर सकते हैं --noIndexRestore


ऐसा लगता है कि यदि आप पासवर्ड संरक्षित मोंगो उदाहरण (और आपको चाहिए!) है तो मैंगोडम्प डॉन `टी काम करते हैं
लुसियानो कैमिलो

3
यह पीडब्लू संरक्षित डीबी पर काम करता है जिसे आपको केवल परम में बेंच पास करने की आवश्यकता है
बेन

2
यह खोजने / forEach / डालने से बहुत तेज़ है, मेरे मामले में 2 मिनट बनाम 2 घंटे
Juraj Paulo

पासवर्ड के लिए संकेत प्राप्त करने के लिए --username के साथ डेटाबेस के लिए उपयोगकर्ता नाम में पास करें लेकिन नहीं --पासवर्ड। पासवर्ड को अपनी कमांड लाइन पर रखना सबसे अच्छा नहीं है (इसे .bash_history या समान में सहेजना समाप्त करना)
Chanoch

माइनर: मुझे कुछ_डॅटबेस के नाम से सबफ़ोल्डर में फ़ाइल मिली, इसलिए यह मेरे लिए काम करता है: mongorestore -d some_other_db -c some_or_other_collection डंप / some_database- कुछ_collection.bson
Aviko

88

वास्तव में, वहाँ है के लिए एक आदेश ले जाने के एक डेटाबेस से दूसरे में एक संग्रह। इसे सिर्फ "चाल" या "प्रतिलिपि" नहीं कहा जाता है।

संग्रह की प्रतिलिपि बनाने के लिए, आप इसे उसी db पर क्लोन कर सकते हैं, फिर क्लोन को स्थानांतरित कर सकते हैं।

क्लोन बनाने के लिए:

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

हिलाने के लिए:

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

संग्रह की प्रतिलिपि बनाने के लिए अन्य उत्तर बेहतर हैं, लेकिन यदि आप इसे स्थानांतरित करना चाहते हैं तो यह विशेष रूप से उपयोगी है।


3
Thx बढ़िया काम करता है! बस एक समापन एपोस्ट्रोप की आवश्यकता है'db1.source_collection'
10

4
इसके बजाय "db.runCommand (..." "आप" केवल एक कमांड कर सकते हैं, "db.adminCommand (..."
Hamid

25

मैं मूंगो क्ली मोंगो डॉक में कनेक्ट फ़ंक्शन का दुरुपयोग करूंगा । तो इसका मतलब है कि आप एक या एक से अधिक कनेक्शन शुरू कर सकते हैं। यदि आप ग्राहक कलेक्शन को टेस्ट से टेस्ट 2 में एक ही सर्वर में कॉपी करना चाहते हैं। पहले आप मोंगो शेल शुरू करें

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

एक सामान्य खोज करें और पहले 20 रिकॉर्ड को test2 में कॉपी करें।

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

या कुछ मानदंडों द्वारा फ़िल्टर करें

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

दूरस्थ सर्वर से कनेक्ट करने के लिए बस लोकलहोस्ट को आईपी या होस्टनाम में बदलें। मैं परीक्षण डेटा को परीक्षण के लिए परीक्षण डेटाबेस में कॉपी करने के लिए इसका उपयोग करता हूं।


4
जैसा कि मैंने जेसन के सुझाव पर टिप्पणी की, ध्यान रखें कि यदि आप जेएस शेल में कॉपी करते हैं तो प्रक्रिया के दौरान BSON दस्तावेज़ JSON में डिकोड हो जाते हैं, इसलिए कुछ दस्तावेज़ प्रकार में बदलाव ला सकते हैं। निष्कासन की सीमाओं के समान विचार हैं और यह डेटाबेस (विशेष रूप से एक ही सर्वर पर) के बीच महत्वपूर्ण मात्रा में डेटा की प्रतिलिपि बनाने के लिए एक धीमी प्रक्रिया है। तो मोंगोडम्प / मोंगोरस्टोरोर FTW :)।
स्टेनी जूल

19

यदि दो दूरस्थ मोंगॉड उदाहरणों के बीच, का उपयोग करें

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

Http://docs.mongodb.org/manual/reference/command/cloneCollection/ देखें


copyIndexesविकल्प क्षेत्र वास्तव में सम्मान नहीं है। इंडेक्स हमेशा कॉपी किए जाते हैं। SERVER-11418
जियानफ्रेंको पी।

6
लपेटें कि db.runCommand () में अर्थात db.runCommand ({cloneCollection: "<collection>", से: "<hostname>", क्वेरी: {<क्वेरी>}})
Daniel de Zwaan

एक दूरस्थ मोंगो से दूसरे में वृद्धिशील अपडेट के लिए इसका उपयोग कैसे किया जा सकता है?
निशांत

मेरे पास उपयोगकर्ता डेटा पूरे दिन में एक आम उदाहरण के लिए जोड़ा जा रहा है। दिन के अंत में मुझे नई जोड़ी गई पंक्तियों को दूसरे मोंगो उदाहरण में स्थानांतरित करने की आवश्यकता है। यह कैसे हासिल किया जा सकता है?
निशांत

@ निशांतकुमार क्वेरी में सेट करने का प्रयास करते हैं: {} यह कोड: $ कहाँ: फ़ंक्शन () {आज = नई तिथि (); // Today.setHours (0,0,0,0); वापसी (यह ।_id.getTimestamp ()> = आज)। Stackoverflow.com/questions/42456375/… देखें ।
es कोलोन

18

मैं आमतौर पर करता हूँ:

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

11

विशाल आकार संग्रह के लिए, आप Bulk.insert () का उपयोग कर सकते हैं

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

इससे काफी समय की बचत होगी । मेरे मामले में, मैं 1219 दस्तावेजों के साथ संग्रह की नकल कर रहा हूं: iter vs Bulk (67 सेकंड बनाम 3 सेकंड)


यह बेहतर है, अधिक कुशल है, हथौड़ों को db से कम करता है, किसी भी आकार के डेटासेट के लिए काम करता है।
जेरेमी

यदि आप 300k से अधिक रिकॉर्ड के साथ ऐसा कर रहे हैं, तो आपको खोज के बाद और। के पहले एक .limit (300000) जोड़ने की आवश्यकता हो सकती है। सिस्टम लॉकअप हो सकता है। मैं आमतौर पर सुरक्षा के लिए थोक परिवर्तनों को लगभग 100k तक सीमित करता हूं। गिनती और सीमा के आधार पर एक लूप में पूरी चीज़ लपेटना।
विजय

6

आप अपने मुद्दे को हल करने के लिए एकत्रीकरण ढांचे का उपयोग कर सकते हैं

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

यह ध्यान दिया जाना चाहिए, कि पुराने कलेक्शन से इंडेक्स को न्यूक्लेओलेशन में कॉपी नहीं किया जाएगा।


5

मुझे पता है कि इस सवाल का जवाब दिया गया है, हालांकि मैं व्यक्तिगत रूप से @JasonMcCays का जवाब इस तथ्य के कारण नहीं दूंगा कि शापर्स स्ट्रीम और यह एक अनंत कर्सर लूप का कारण बन सकता है यदि संग्रह अभी भी उपयोग किया जा रहा है। इसके बजाय मैं एक स्नैपशॉट का उपयोग करेगा ():

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

@bens का उत्तर भी एक अच्छा है और न केवल संग्रह के गर्म बैकअप के लिए अच्छी तरह से काम करता है, बल्कि mongorestore को भी उसी mongod को साझा करने की आवश्यकता नहीं है।


5

यह सिर्फ एक विशेष मामला हो सकता है, लेकिन दो यादृच्छिक स्ट्रिंग फ़ील्ड (लंबाई 15-20 वर्ण) के साथ 100k दस्तावेज़ों के संग्रह के लिए, एक गूंगा मैप्रेड्यूज़ का उपयोग करके लगभग दो बार तेजी से मिल-डालें / copyTo:

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

5

Pymongo का उपयोग करना, आपको एक ही mongod पर दोनों डेटाबेस रखने की आवश्यकता है, मैंने निम्नलिखित कार्य किया:


db = मूल डेटाबेस
db2 = डेटाबेस को कॉपी किया जाना है

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

1
यदि डेटा का आकार बड़ा है, तो इसमें बहुत समय लगेगा। वैकल्पिक रूप से आप उपयोग कर सकते हैं bulk_insert
निशांत

1
हां, यह मेरे लिए काम करने का एक त्वरित और गंदा तरीका था, मेरा डेटाबेस बहुत बड़ा नहीं था, लेकिन छोटा भी नहीं था और बहुत लंबा नहीं था, लेकिन हाँ आप सही हैं।
vbhakta

2

यह आपकी समस्या का समाधान नहीं करेगा लेकिन मोंगोडब शेल में एक copyToविधि है जो एक संग्रह को उसी डेटाबेस में दूसरे में कॉपी करता है :

db.mycoll.copyTo('my_other_collection');

यह BSON से JSON में भी अनुवाद करता है, इसलिए mongodump/ mongorestoreजाने का सबसे अच्छा तरीका है, जैसा कि अन्य ने कहा है।


अति उत्कृष्ट। अफसोस की बात है कि मैंगो शेल संदर्भ इस पद्धति का उल्लेख नहीं करता है।
पीजी

हाँ, मुझे पता है, लेकिन MongoDB शेल भयानक है, यदि आप db.collname टाइप करते हैं। [TAB] आपको संग्रह ऑब्जेक्ट पर सभी उपलब्ध विधियाँ दिखाई देंगी। यह टिप अन्य सभी वस्तुओं के लिए काम करता है।
रॉबर्टो

समस्या उन आदेशों के लिए मदद की कमी है! यह कोड को देखने में सक्षम होने के लिए उपयोगी है, हालांकि एक विधि कॉल के लिए पार्न्स को छोड़ कर।
पीजी

2
अफसोस की बात है कि संस्करण 3.0 से अब इस कमांड को हटा दिया गया है।
हैरी

2

यदि RAM लूप की insertManyतुलना में तेज़ तरीके से उपयोग करने वाली कोई समस्या नहीं है 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())

1

यदि कुछ हर्को यूजर्स यहां ठोकर खाते हैं और मेरे जैसा चाहते हैं कि मैं स्टेजिंग डेटाबेस से प्रोडक्शन डेटाबेस या इसके विपरीत कुछ डेटा कॉपी करना चाहता हूं तो आप इसे बहुत आसानी से कैसे कर सकते हैं (एनबी मुझे आशा है कि इसमें कोई टाइपो नहीं है, इसे एटीएम की जांच नहीं कर सकते।) मैं कोड 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"

1

आप हमेशा रोबोमोंगो का उपयोग कर सकते हैं। जैसा कि v0.8.3 एक उपकरण है जो संग्रह पर राइट-क्लिक करके और "डेटाबेस के लिए कॉपी संग्रह" का चयन करके ऐसा कर सकता है

जानकारी के लिए, http://blog.robomongo.org/whats-new-in-robomongo-0-8-3/ देखें।

यह सुविधा 0.8.5 में इसकी छोटी प्रकृति के कारण हटा दी गई थी, इसलिए यदि आप इसे आज़माना चाहते हैं तो आपको 0.8.3 या 0.8.4 का उपयोग करना होगा।


6
रोबोमोंगो की यह विशेषता अभी भी अस्थिर है। यह काम करने का 50/50 मौका है।
तेरह

2
ऐसा लगता है कि 0.8.5
कारसेल

0

मेरे मामले में, मुझे अपने नए संग्रह में पुराने संग्रह से विशेषताओं का सबसेट उपयोग करना था। इसलिए मैंने नए कलेक्शन पर कॉल करते समय उन विशेषताओं को चुनना समाप्त कर दिया।

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

0

"Mong3DB के लिए Studio3T" का उपयोग करें, जिसमें डेटाबेस, संग्रह या विशिष्ट संग्रह डाउनलोड लिंक पर क्लिक करके निर्यात और आयात उपकरण हैं: https://studio3t.com/download/


हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.