Есть ли простой способ сделать это?
Есть ли простой способ сделать это?
Ответы:
На данный момент в 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
.
На самом деле, это команда , чтобы переместить коллекцию из одной базы данных в другую. Это просто не называется «переместить» или «скопировать».
Чтобы скопировать коллекцию, вы можете клонировать ее на том же БД, а затем переместить клон.
Клонировать:
> 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 . так что это означает, что вы можете установить одно или несколько соединений. если вы хотите скопировать коллекцию клиентов из test в test2 на том же сервере. сначала вы начинаете монго оболочки
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
для коллекций большого размера вы можете использовать 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.
Это может быть просто особый случай, но для коллекции документов размером 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)
Это не решит вашу проблему, но оболочка mongodb имеет copyTo
метод, который копирует коллекцию в другую в той же базе данных :
db.mycoll.copyTo('my_other_collection');
Он также переводит с BSON в формате JSON, поэтому mongodump
/ mongorestore
лучший путь, как уже говорили другие.
Если оперативная память не является проблемой, использование 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. Начиная с версии 0.8.3 существует инструмент, который может сделать это, щелкнув правой кнопкой мыши коллекцию и выбрав «Копировать коллекцию в базу данных».
Для получения дополнительной информации см. Http://blog.robomongo.org/whats-new-in-robomongo-0-8-3/.
Эта функция была удалена в 0.8.5 из-за ее ошибочной природы, поэтому вам придется использовать 0.8.3 или 0.8.4, если вы хотите попробовать ее.
В моем случае мне пришлось использовать подмножество атрибутов из старой коллекции в моей новой коллекции. В итоге я выбрал эти атрибуты при вызове insert для новой коллекции.
db.<sourceColl>.find().forEach(function(doc) {
db.<newColl>.insert({
"new_field1":doc.field1,
"new_field2":doc.field2,
....
})
});`
используйте «Studio3T for MongoDB» с инструментами «Экспорт» и «Импорт», щелкнув ссылку на базу данных, коллекцию или ссылку для загрузки конкретной коллекции: https://studio3t.com/download/
Это можно сделать с помощью db.copyDatabase
метода Монго :
db.copyDatabase(fromdb, todb, fromhost, username, password)
Ссылка: http://docs.mongodb.org/manual/reference/method/db.copyDatabase/