Как я могу скопировать одну коллекцию из MongoDB с помощью pymongo и вставить в другую пустую коллекцию?

#python #mongodb #pymongo

#python #mongodb #pymongo

Вопрос:

  1. Я хочу скопировать полную коллекцию (например, имя ‘home’).
  2. Затем внесите некоторые изменения в «домашнюю» коллекцию или удалите документ внутри нее (не коллекцию).
  3. А затем замените измененную «домашнюю» коллекцию на состояние по умолчанию из пункта 1.

Я делаю следующее:

 db = client["database"]
home = db['home'].find()  # get collection.
db['home'].remove({})  # remove doc from home
for i in home:
      self.db['home'].insert(i)
  

Но коллекция пуста.

Комментарии:

1. в mongodb есть функция copyTo , которую вы можете использовать. обратитесь https://docs.mongodb.com/manual/reference/method/db.collection.copyTo /

2. Но если я удалю документы из «home», а затем скопирую их, они будут пустыми.

Ответ №1:

Проблема с вашим примером кода заключается в том, что find() возвращает курсор базы данных в коллекцию, а не все документы в коллекции. Поэтому, когда вы remove используете все документы из home коллекции, курсор также будет указывать на пустую коллекцию.

Чтобы скопировать коллекцию в другую коллекцию на том же сервере, вы можете использовать операторы агрегации MongoDB $match и $ out

 pipeline = [ {"$match": {}}, 
             {"$out": "destination_collection"},
]
db.source_collection.aggregate(pipeline)
  

Используя ваш пример кода, теперь вы можете сделать

 source = db["source_collection"]
destination = db["destination_collection"]

# Remove all documents, or make modifications. 
source.remove({}) 

# Restore documents from the source collection.  
for doc in destination: 
      source.insert(doc)
# or instead you can just use the same aggregation method above but reverse the collection name. 
  

Примечание: db.collection.CopyTo() устарел с версии MongoDB v3.0.

Если вы хотите скопировать на другой сервер MongoDB, вы можете использовать db.cloneCollection() . В PyMongo это была бы команда, приведенная ниже:

 db.command("cloneCollection", **{'collection': "databaseName.source_collection", 'from': "another_host:another_port"})
  

В зависимости от вашей общей цели, вы можете найти методы резервного копирования MongoDB полезными.

Комментарии:

1. Я думаю, что должно быть наоборот. для документа в источнике: destination.insert (doc)

2. Вопрос на шаге 3 заключается в том, чтобы восстановить ее обратно в исходную исходную коллекцию после удаления источника. Если вы просто переходите от источника к месту назначения, вы можете просто использовать $out конвейер агрегации и остановиться на этом этапе.

Ответ №2:

Это может быть самый простой способ сделать это, я лично предпочитаю его, поэтому вы можете добавлять столько фильтров, сколько захотите:

 from pymongo import MongoClient

def CopyFromColl1ToColl2(database1,collection1,database2,collection2):
    db1 = MongoClient('mongodb://127.0.0.1:27017')[database1][collection1]
    db2 = MongoClient('mongodb://127.0.0.1:27017')[database2][collection2]
    #here you can put the filters you like.
    for a in db1.find():
        try:
            db2.insert(a)
            print(a)
        except:
            print('did not copy')

# You can choose the database name and the collection name
CopyFromColl1ToColl2('database1','collection1','database2','collection2')
  

Ответ №3:

Должны быть лучшие способы, но mongo> 4.0 устарел команды copydb / copycollection. Что вы можете сделать в качестве альтернативы, вы можете для перебора коллекций и для перебора документов и вставки нужной базы данных / коллекции.

     db1_collections = client.db1.list_collection_names()

    for collection in db1_collections:
        collections_cursor = client.db1[collection].find()
        clt = client.db2[collection]
        for document in collections_cursor:
            clt.with_options(write_concern=WriteConcern(w=0)).insert_one(document)