如何通过略微修改(Java驱动程序)复制MongoDB中的大量条目?

时间:2015-08-07 13:56:40

标签: java mongodb mongodb-java

想象一下,我有一个包含以下字段的MongoDB集合:

  1. buildingID(String)
  2. projectID(String)
  3. coords(经度/纬度坐标数组)
  4. 我有很多记录,通过projectID属性 - 分配给项目A.现在我想

    1. 获取属于项目A的所有记录,
    2. 复制它们以便
    3. 在新记录中,除projectID以外的所有字段都等于原始字段和
    4. projectID等于项目B。
    5. 我可以这样做:

      Collection coll = getDb().getCollection("MyColl");
      
      final Map<String,Object> query = new HashMap<>();
      query.put("projectid", "projectA");
      
      DBCursor cursor = coll.find(new BasicDBObject(query));
      
      while (cursor.hasNext()) {
          final BasicDBObject curRecord = cursor.next();
      
          final BasicDBObject newRecord = clone(curRecord);
          newRecord.set("projectid", "projectB");
          coll.insert(newRecord);
      }
      

      clone会创建curRecord

      的副本

      有更优雅的方法吗?我可以避免将数据从MongoDB中导入Java并重新导入MongoDB吗?

1 个答案:

答案 0 :(得分:1)

确实有更优雅的方式来做到这一点。使用Bulk Operations API,因为这会大大减少对服务器的写入和响应次数:

    BulkWriteOperation bulk = coll.initializeOrderedBulkOperation();
    Integer count = 0;

    DBCursor cursor = coll.find(new BasicDBObject("projectid", "projectA"));

    while (cursor.hasNext()) {
        DBObject curRecord = cursor.next();
        curRecord.removeField("_id");  // why bother with a clone when you can remove the _id
        curRecord.put("projectid","projectB"); // replace the projectid
        bulk.insert(curRecord);
        count++;

        if ( count % 1000 == 0 ) {
            bulk.execute();
            bulk = collection.initializeOrderedBulkOperation();
        }
    }

    if (count % 1000 != 0 )
        bulk.execute();

现在每1000次操作只会从服务器发送/接收内容。这也是一个内部限制,但它有助于限制内存消耗以自行管理。