มีวิธีง่าย ๆ ในการทำเช่นนี้?
มีวิธีง่าย ๆ ในการทำเช่นนี้?
คำตอบ:
ในตอนนี้ไม่มีคำสั่งใน MongoDB ที่จะทำเช่นนี้ โปรดทราบตั๋วจิระที่มีการร้องขอคุณลักษณะที่เกี่ยวข้อง
คุณสามารถทำสิ่งที่ชอบ:
db.<collection_name>.find().forEach(function(d){ db.getSiblingDB('<new_database>')['<collection_name>'].insert(d); });
โปรดทราบว่าด้วยสิ่งนี้ฐานข้อมูลทั้งสองจะต้องใช้ Mongo เดียวกันร่วมกันเพื่อใช้งานได้
นอกจากนี้คุณสามารถทำ mongodump ของคอลเลกชันจากฐานข้อมูลหนึ่งและจากนั้น mongorestore คอลเลกชันไปยังฐานข้อมูลอื่น
วิธีที่ดีที่สุดคือทำ mongodump จากนั้น mongorestore
คุณสามารถเลือกคอลเลกชันผ่าน:
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
กระบวนการนี้เป็นไปโดยอัตโนมัติและคุณสามารถปิดการใช้งานด้วย
ที่จริงมีเป็นคำสั่งไปยังย้ายการเก็บรวบรวมจากฐานข้อมูลหนึ่งไปยังอีก มันไม่ได้เรียกว่า "ย้าย" หรือ "คัดลอก"
หากต้องการคัดลอกคอลเล็กชันคุณสามารถโคลนได้บน 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?
คำตอบอื่น ๆ จะดีกว่าสำหรับการคัดลอกคอลเลกชัน แต่มีประโยชน์อย่างยิ่งหากคุณต้องการย้าย
'db1.source_collection'
ฉันจะละเมิดฟังก์ชั่นการเชื่อมต่อใน Mongo CLI Mongo doc ดังนั้นหมายความว่าคุณสามารถเริ่มต้นการเชื่อมต่อหนึ่งรายการขึ้นไป ถ้าคุณต้องการคัดลอกคอลเลกชันของลูกค้าจากการทดสอบไปยัง test2 ในเซิร์ฟเวอร์เดียวกัน ก่อนอื่นให้คุณเริ่มต้น mongo shell
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); });
เพียงแค่เปลี่ยน localhost เป็น IP หรือชื่อโฮสต์เพื่อเชื่อมต่อกับเซิร์ฟเวอร์ระยะไกล ฉันใช้สิ่งนี้เพื่อคัดลอกข้อมูลทดสอบไปยังฐานข้อมูลทดสอบเพื่อทำการทดสอบ
หากระหว่างสองอินสแตนซ์ MongoS ระยะไกลใช้
{ cloneCollection: "<collection>", from: "<hostname>", query: { <query> }, copyIndexes: <true|false> }
ดูhttp://docs.mongodb.org/manual/reference/command/cloneCollection/
copyIndexes
ฟิลด์ตัวเลือกที่จริงไม่ได้เป็นที่เคารพนับถือ ดัชนีจะถูกคัดลอกเสมอ ดู SERVER-11418
ฉันมักจะทำ:
use sourcedatabase;
var docs=db.sourcetable.find();
use targetdatabase;
docs.forEach(function(doc) { db.targettable.insert(doc); });
สำหรับคอลเลกชันขนาดใหญ่คุณสามารถใช้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.oldCollection.aggregate([{$out : "newCollection"}])
มันจะถูกบันทึกไว้ว่าดัชนีจาก oldCollection จะไม่ถูกคัดลอกใน newCollection
ฉันรู้ว่าคำถามนี้ได้รับการตอบแล้ว แต่โดยส่วนตัวแล้วฉันจะไม่ตอบ @JasonMcCays เนื่องจากข้อเท็จจริงที่ว่าเคอร์เซอร์สตรีมและสิ่งนี้อาจทำให้เกิดเคอร์เซอร์ที่ไม่สิ้นสุดหากยังคงมีการใช้คอลเลกชัน แต่ฉันจะใช้ภาพรวม ():
http://www.mongodb.org/display/DOCS/How+to+do+Snapshotted+Queries+in+the+Mongo+Database
@bens คำตอบก็เป็นสิ่งที่ดีและทำงานได้ดีสำหรับการสำรองข้อมูลคอลเลกชันที่ร้อนแรงไม่เพียง แต่ mongorestore ไม่จำเป็นต้องแบ่งปัน mongod เดียวกัน
นี่อาจเป็นกรณีพิเศษ แต่สำหรับการรวบรวมเอกสารขนาด 100k ที่มีเขตข้อมูลสตริงแบบสุ่มสองช่อง (ความยาว 15-20 ตัวอักษร) การใช้ mapreduce แบบใบ้นั้นเร็วกว่าการค้นหา - แทรก / คัดลอกเกือบสองเท่า:
db.coll.mapReduce(function() { emit(this._id, this); }, function(k,vs) { return vs[0]; }, { out : "coll2" })
การใช้ pymongo คุณต้องมีฐานข้อมูลทั้งสองใน mongod เดียวกันฉันทำสิ่งต่อไปนี้:
db = ฐานข้อมูลดั้งเดิม
db2 = ฐานข้อมูลที่จะคัดลอกไปยัง
cursor = db["<collection to copy from>"].find()
for data in cursor:
db2["<new collection>"].insert(data)
สิ่งนี้จะไม่แก้ปัญหาของคุณ แต่ mongodb shell มีcopyTo
วิธีการที่จะทำการคัดลอกคอลเล็กชันไปยังอีกอันหนึ่งในฐานข้อมูลเดียวกัน :
db.mycoll.copyTo('my_other_collection');
นอกจากนี้ยังแปลจาก BSON เป็น JSON ดังนั้นmongodump
/ mongorestore
เป็นวิธีที่ดีที่สุดที่จะไปตามที่คนอื่น ๆ ได้กล่าวไว้
หาก 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())
ในกรณีที่ผู้ใช้ heroku บางคนสะดุดที่นี่และฉันต้องการคัดลอกข้อมูลบางส่วนจากฐานข้อมูลการจัดเตรียมไปยังฐานข้อมูลการผลิตหรือในทางกลับกันนี่คือวิธีที่คุณทำได้อย่างสะดวกมาก (NB ฉันหวังว่าจะไม่มีการพิมพ์ผิดในนั้น ฉันจะลองยืนยันความถูกต้องของรหัสโดยเร็ว):
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"
คุณสามารถใช้ Robomongo ได้ตลอดเวลา ตั้งแต่ v0.8.3 มีเครื่องมือที่สามารถทำได้โดยการคลิกขวาบนคอลเลกชันและเลือก "คัดลอกคอลเลกชันไปยังฐานข้อมูล"
ดูรายละเอียดได้ที่http://blog.robomongo.org/whats-new-in-robomongo-0-8-3/
คุณลักษณะนี้ถูกลบออกใน 0.8.5เนื่องจากลักษณะบั๊กกี้ของมันดังนั้นคุณจะต้องใช้ 0.8.3 หรือ 0.8.4 หากคุณต้องการทดลองใช้
ในกรณีของฉันฉันต้องใช้ชุดย่อยของคุณลักษณะจากชุดเก่าในชุดใหม่ของฉัน ดังนั้นฉันจึงเลือกคุณลักษณะเหล่านั้นในขณะที่เรียกใช้การแทรกบนคอลเล็กชันใหม่
db.<sourceColl>.find().forEach(function(doc) {
db.<newColl>.insert({
"new_field1":doc.field1,
"new_field2":doc.field2,
....
})
});`
ใช้ "Studio3T สำหรับ MongoDB" ที่มีเครื่องมือส่งออกและนำเข้าโดยคลิกที่ฐานข้อมูลคอลเลกชันหรือลิงค์ดาวน์โหลดคอลเล็กชันเฉพาะ: https://studio3t.com/download/
สิ่งนี้สามารถทำได้โดยใช้db.copyDatabase
วิธีของ Mongo :
db.copyDatabase(fromdb, todb, fromhost, username, password)
การอ้างอิง: http://docs.mongodb.org/manual/reference/method/db.copyDatabase/