【问题标题】:mongo copy from one collection to another (on the same db)mongo 从一个集合复制到另一个集合(在同一个数据库上)
【发布时间】:2022-04-04 18:54:54
【问题描述】:

我有一个名为test 的mongo db,在这个db 中有两个集合collection1collection1_backup。 如何用collection1_backup的数据替换collection1的内容。

【问题讨论】:

    标签: mongodb


    【解决方案1】:

    完成此操作的最佳方法(考虑到集合的名称以_backup 结尾)可能是使用 mongorestore:http://docs.mongodb.org/manual/reference/mongorestore/

    但是在这种情况下,这取决于。如果集合未分片,您可以使用 renameCollection ( http://docs.mongodb.org/manual/reference/command/renameCollection/ ) 或者您可以使用更手动的方法(在 JavaScript 代码中):

    db.collection1.drop(); // Drop entire other collection
    db.collection1_backup.find().forEach(function(doc){
       db.collection1.insert(doc); // start to replace
    });
    

    这些是最常用的方法。

    【讨论】:

    • 与聚合相比最慢的方法。
    • @DenisDenisov 你有证据吗?我想这两个(手动方法和聚合框架,这种方法肯定不会比实际上专门设计用于复制表的复制功能快,尽管它可能正在考虑它可能采取的安全措施)将复制相对相同,他们需要将所有行读入活动工作集中,然后将它们保存下来,我真的不知道聚合框架会更快,更不用说它不是真的为这样的事情设计的
    • 是的,我刚刚检查了一个大集合。集合和索引使用wiredTiger.configString='block_compressor=zstd'percona-server-mongodb-server-4.2.6-6.el7.x86_64 几乎立即执行了聚合。
    • @DenisDenisov instnatly?即使在 2m 条记录的集合上,另一个用户记录了大约 3 分钟 stackoverflow.com/a/37870870/383478 并且立即比磁盘实际写入的速度更快,因此违反了科学定律
    • 无论如何,db.collection1_backup.aggregate([ { $match: {} }, { $out: "collection1" } ]) 工作得更快。 find().forEach(..insert=~100rec/s forums.meteor.com/t/… mongobooster.useresponse.com/topic/… stackoverflow.com/questions/31466623/…
    【解决方案2】:

    这可以使用简单的命令来完成:

    db.collection1_backup.aggregate([ { $match: {} }, { $out: "collection1" } ])
    

    此命令将删除collection1的所有文档,然后在collection1中克隆collection1_backup。

    通用命令是

    db.<SOURCE_COLLECTION>.aggregate([ { $match: {} }, { $out: "<TARGET_COLLECTION>" } ])
    

    如果 TARGET_COLLECTION 不存在,上述命令将创建它。

    【讨论】:

      【解决方案3】:

      也很有用: 将集合导出到 json 文件

      mongoexport --collection collection1_backup --out collection1.json
      

      从json文件导入集合

      mongoimport --db test --collection collection1 --file collection1.json
      

      要从备份/转储文件中导入单个集合,需要将 *.bson 文件转换为 *.json 通过使用

      bsondump collection1_backup.bson > collection1_backup.json
      

      【讨论】:

      • 一般来说,复制集合时最好使用mongodumpmongorestore,因为将文档转换为JSON 并返回可能会影响data type fidelity。 BSON 中存在一些数据类型,它们可以有一个 different representation in JSON,其中没有严格的 JSON 等价物。根据您的数据,使用mongoimport/mongoexport 可能没问题,但这是一个需要注意的重要警告。
      • @Stennie 同样重要的是要注意执行 mongodump / mongorestore 将保留索引。因此,如果您尝试在集合之间复制文档,您将无法恢复。如果您尝试在集合之间复制文档,则应使用 mongoexport 和 mongoimport。
      • @ivandov 您可以使用mongorestore --noIndexRestore 跳过重新创建索引(除了必需的_id 索引)。请注意,mongorestore(在 MongoDB 3.4 中)只进行插入;如果存在具有相同_id 的文档,则不会对其进行更新或替换。 mongoimport 工具支持 upserts(在 3.4 中支持合并),但适用于文本格式而不是 MongoDB 的原生 BSON 格式。如果您想在 MongoDB 部署之间以相同的方式重新创建数据(以及可选的集合元数据),mongodumpmongorestore 仍然是推荐的选项。
      【解决方案4】:

      只需这样做。

      //删除集合1

      db.collection1.drop();
      

      //从collection1_backup复制数据到collection1

      db.collection1.insert(db.collection1_backup.find({},{_id:0}).toArray());
      

      【讨论】:

        【解决方案5】:

        更好的方法是使用.toArray()

         db.collection1.drop(); // Drop entire other collection
        
         // creates an array which can be accessed from "data"
         db.collection1_backup.find().toArray(function(err, data) {
        
              // creates a collection and inserting the array at once
              db.collection1.insert(data);
         });
        

        【讨论】:

        • 尺寸优化怎么样?如果我的收藏是 2GB,我应该有 2GB 内存吗?
        【解决方案6】:

        您可以使用一个简单的命令来备份 MongoDB 集合。它仅适用于 MongoDB 4.0 或更早版本

        db.sourceCollectionName.copyTo('targetCollectionName')
        

        您的 targetCollectionName 必须在 Single(') 或 Double(") 引用中

        注意:

        db.collection.copyTo() 方法在内部使用 eval 命令。作为 结果, db.collection.copyTo() 操作需要一个全局锁 阻止所有其他读写操作,直到 db.collection.copyTo() 完成。

        【讨论】:

        • copyTo 可能需要一些 special permissions 并且在从 BSON 转换为 JSON 时也可能会更改数据。
        • copyTo 已弃用:docs.mongodb.com/manual/reference/method/db.collection.copyTo。引用:“从 4.2 版开始,MongoDB 删除了 eval 命令。已弃用的 db.collection.copyTo() 包装了 eval 命令,只能针对 MongoDB 4.0 或更早版本运行。有关行为和示例,请参阅 4.0或更早版本的手册。”
        【解决方案7】:

        使用 Java 驱动程序

        试试下面的一个:

        public void copyTo(String db,String sourceCollection,String destinationCollection,int limit) throws        
        UnknownHostException {
        
            MongoClient mongo = new MongoClient("localhost", 27017);
            DB database = mongo.getDB(db);
            DBCollection collection = database.getCollection(sourceCollection);
            DBCursor dbCursor = collection.find().limit(limit);
            List<DBObject> list =  dbCursor.toArray();
            DBCollection destination =  database.getCollection(destinationCollection);
            destination.insert(list, WriteConcern.NORMAL); //WRITE CONCERN is based on your requirment.
        
        }
        

        【讨论】:

          【解决方案8】:

          丢弃收集1

          然后使用这个查询

          var cursor = db.collection1_backup.find();
          var data = [];
          while(cursor.hasNest()){
              data.push(cursor.next());
          }
          
          db.collection1.insertMany(data)
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2016-08-24
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-07-18
            • 2020-07-17
            相关资源
            最近更新 更多