Есть простой способ сделать это?
Как скопировать коллекцию из одной базы данных в другую в MongoDB
Ответы (21)
На данный момент в MongoDB нет команды, которая бы это сделала. Обратите внимание на заявку JIRA с запросом соответствующей функции.
Вы можете сделать что-то вроде:
db.<collection_name>.find().forEach(function(d){ db.getSiblingDB('<new_database>')['<collection_name>'].insert(d); });
Обратите внимание, что при этом две базы данных должны использовать один и тот же mongod, чтобы это работало.
Помимо этого, вы можете выполнить mongodump коллекции из одной базы данных, а затем сохранить коллекцию в другой базе данных.
Лучше всего сделать 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
.
mongodump --db=some_database --collection=some_collection --archive=- | mongorestore --nsFrom="some_database.some_collection" --nsTo="some_or_other_database.some_or_other_collection" --archive=-
- person Wernfried Domscheit; 01.04.2021
Собственно, есть команда переместить коллекцию из одной базы данных в другую. Это просто не называется перемещением или копированием.
Чтобы скопировать коллекцию, вы можете клонировать ее в той же базе данных, а затем переместить клонированную коллекцию.
Чтобы клонировать:
> use db1
switched to db 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'
}
);
Другие ответы лучше подходят для копирования коллекции, но это особенно полезно, если вы хотите переместить ее.
'db1.source_collection'
- person andrrs; 29.01.2015
Я бы злоупотребил функцией подключения в mongo cli монго документ. это означает, что вы можете запустить одно или несколько подключений. если вы хотите скопировать коллекцию клиентов из test в test2 на том же сервере. сначала вы запускаете оболочку mongo
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 или имя хоста для подключения к удаленному серверу. Я использую это для копирования тестовых данных в тестовую базу данных для тестирования.
Если между двумя удаленными экземплярами mongod используйте
{ cloneCollection: "<collection>", from: "<hostname>", query: { <query> }, copyIndexes: <true|false> }
См. http://docs.mongodb.org/manual/reference/command/cloneCollection/ < / а>
copyIndexes
фактически не соблюдается. Индексы всегда копируются. См. SERVER-11418.
- person Gianfranco P.; 17.04.2014
cloneCollection
был удален в MongoDB версии 4.4, поэтому он больше не доступен в текущих выпусках.
- person Wernfried Domscheit; 13.05.2021
Обычно я делаю:
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.
newCollection
удаляется перед вставкой новых данных.
- person Wernfried Domscheit; 13.05.2021
Я знаю, что на этот вопрос был дан ответ, однако я лично не стал бы отвечать на @JasonMcCays из-за того, что курсоры текут, и это может вызвать бесконечный цикл курсора, если коллекция все еще используется. Вместо этого я бы использовал snapshot ():
http://www.mongodb.org/display/DOCS/How+to+do+Snapshotted+Queries+in+the+Mongo+Database
Ответ @bens также хорош и хорошо работает для горячих резервных копий коллекций, не только, но mongorestore не должен использовать один и тот же mongod.
Это может быть просто особый случай, но для коллекции из 100 тыс. Документов с двумя случайными строковыми полями (длина составляет 15-20 символов) использование немого mapreduce почти в два раза быстрее, чем find-insert / copyTo:
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)
Если оперативная память не является проблемой, использование 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())
Есть разные способы сделать коллекционную копию. Обратите внимание, что копирование может происходить в той же базе данных, другой базе данных, сегментированной базе данных или mongod
экземплярах. Некоторые инструменты могут быть эффективными для копирования коллекций большого размера.
Агрегация с $ merge: записывает результаты конвейера агрегации в указанную коллекцию. Обратите внимание, что копирование может происходить в разных базах данных, даже в сегментированных коллекциях. Создает новую или заменяет существующую коллекцию. Новое в версии 4.2. Пример: db.test.aggregate([ { $merge: { db: "newdb", coll: "newcoll" }} ])
Агрегация с $ out: записывает результаты конвейера агрегации в указанную коллекцию. Обратите внимание, что копирование может происходить только в той же базе данных. Создает новую или заменяет существующую коллекцию. Пример: db.test.aggregate([ { $out: "newcoll" } ])
mongoexport и mongoimport: это инструменты командной строки. mongoexport
производит экспорт данных коллекции в формате JSON или CSV. Выходные данные экспорта используются в качестве источника для целевой коллекции с использованием mongoimport
.
mongodump и mongorestore: это инструменты командной строки. mongodump
утилита предназначена для создания двоичного экспорта содержимого базы данных или коллекции. Программа mongorestore
загружает данные из двоичного дампа базы данных, созданного mongodump
, в место назначения.
db.cloneCollection (): копирует коллекцию из удаленного mongod
экземпляра в текущий mongod
экземпляр. Не рекомендуется, начиная с версии 4.2.
db.collection.copyTo (): копирует все документы из коллекции в новую коллекцию (в той же базе данных). Не рекомендуется, начиная с версии 3.0. Начиная с версии 4.2 MongoDB эта команда недействительна.
ПРИМЕЧАНИЕ. Если не указано иное, приведенные выше команды выполняются из mongo
оболочки.
Ссылка: Руководство MongoDB.
Вы также можете использовать любимый язык программирования (например, Java) или среду (например, NodeJS) с помощью соответствующего программного обеспечения драйвера для написания программы для выполнения копирования - это может включать использование операций поиска и вставки или другого метода. Этот поиск-вставку также можно выполнить из оболочки mongo
.
Вы также можете сделать копию коллекции с помощью программ с графическим интерфейсом, таких как MongoDB Compass.
Как указано в других ответах, самым быстрым решением должно быть mongodump / mongorestore
. Нет необходимости сохранять дамп на локальный диск, вы можете передать дамп прямо в mongorestore:
mongodump --db=some_database --collection=some_collection --archive=- | mongorestore --nsFrom="some_database.some_collection" --nsTo="some_or_other_database.some_or_other_collection" --archive=-
Если вы запускаете общий кластер, новая коллекция по умолчанию не сегментируется. Все данные изначально записываются в ваш основной шард. Это может вызвать проблемы с дисковым пространством и создать дополнительную нагрузку на ваш кластер для балансировки < / а>. Лучше предварительно разделить свою коллекцию, как это было раньше вы импортируете данные:
sh.shardCollection("some_or_other_database.some_or_other_collection", { <shard_key>: 1 });
db.getSiblingDB("config").getCollection("chunks").aggregate([
{ $match: { ns: "some_database.some_collection"} },
{ $sort: { min: 1 } },
{ $skip: 1 }
], { allowDiskUse: true }).forEach(function (chunk) {
sh.splitAt("some_or_other_database.some_or_other_collection", chunk.min)
})
Это не решит вашу проблему, но оболочка mongodb имеет _1 _ метод, который копирует коллекцию в другую в той же базе данных:
db.mycoll.copyTo('my_other_collection');
Он также переводится из BSON в JSON, поэтому _3 _ / _ 4_ - лучший способ, как говорили другие.
В случае, если некоторые пользователи heroku спотыкаются здесь и, как я, хотят скопировать некоторые данные из промежуточной базы данных в производственную базу данных или наоборот, вот как вы это делаете очень удобно (NB, я надеюсь, что там нет опечаток, не могу проверить это atm., Попробую как можно скорее подтвердить действительность кода):
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"
Вы всегда можете использовать Робомонго. Начиная с v0.8.3 есть инструмент, который может сделать это, щелкнув правой кнопкой мыши коллекцию и выбрав «Копировать коллекцию в базу данных».
Подробнее см. http://blog.robomongo.org/whats-new-in-robomongo-0-8-3/
Эта функция была удалена в 0.8.5 из-за ее ошибочного характера, поэтому вам придется используйте 0.8.3 или 0.8.4, если хотите попробовать.
используйте «Studio3T для MongoDB», у которого есть инструменты экспорта и импорта, щелкнув базу данных, коллекции или ссылку для загрузки конкретной коллекции: https://studio3t.com/download/
В моем случае мне пришлось использовать подмножество атрибутов из старой коллекции в моей новой коллекции. В итоге я выбрал эти атрибуты при вызове вставки в новую коллекцию.
db.<sourceColl>.find().forEach(function(doc) {
db.<newColl>.insert({
"new_field1":doc.field1,
"new_field2":doc.field2,
....
})
});`
Чтобы скопировать коллекцию (myCollection1) из одной базы данных в другую в MongoDB,
**Server1:**
myHost1.com
myDbUser1
myDbPasword1
myDb1
myCollection1
outputfile:
myfile.json
**Server2:**
myHost2.com
myDbUser2
myDbPasword2
myDb2
myCollection2
ты можешь сделать это:
mongoexport --host myHost1.com --db myDb1 -u myDbUser1 -p myDbPasword1 --collection myCollection1 --out myfile.json
тогда:
mongoimport --host myHost2.com --db myDb2 -u myDbUser2 -p myDbPasword2 --collection myCollection2 --file myfile.json
Другой случай, используя файл CSV:
Server1:
myHost1.com
myDbUser1
myDbPasword1
myDb1
myCollection1
fields.txt
fieldName1
fieldName2
outputfile:
myfile.csv
Server2:
myHost2.com
myDbUser2
myDbPasword2
myDb2
myCollection2
ты можешь сделать это:
mongoexport --host myHost1.com --db myDb1 -u myDbUser1 -p myDbPasword1 --collection myCollection1 --out myfile.csv --type=csv
добавьте типы столбцов в файл csv (name1.decimal (), name1.string () ..), а затем:
mongoimport --host myHost2.com --db myDb2 -u myDbUser2 -p myDbPasword2 --collection myCollection2 --file myfile.csv --type csv --headerline --columnsHaveTypes
Это можно сделать с помощью метода Mongo db.copyDatabase
:
db.copyDatabase(fromdb, todb, fromhost, username, password)
Ссылка: http://docs.mongodb.org/manual/reference/method/db.copyDatabase/