MongoDB:将数组复制到同一文档中的另一个数组

时间:2016-07-28 10:33:11

标签: arrays mongodb

我目前正在与MongoDB合作开设一家在线珠宝店,我需要将“品牌”阵列中包含的品牌复制到一个名为“brandsNetherlands”的新阵列中。

<% 
 try{
    String name=request.getParameter("username");
    String abc=request.getParameter("password");

    String Sql="select * from login where username='"+name+"' AND password='"+abc+"'";

     c1.st.executeQuery(Sql);   
      out.println("aa");
    }
    catch(SQLException ex)
     {
     out.println(ex);
     }
   %>

这是“批发商”集合中包含的其中一个文件的当前构建示例。我需要一个非静态脚本,允许我将“brands”数组中列出的品牌移动或复制到空的“brandsNetherlands”数组中。这可能吗?

1 个答案:

答案 0 :(得分:0)

对于相对较小的数据,您可以使用 snapshot 使用光标的 forEach() 方法迭代集合并更新每个数据,从而实现上述目标。文件如下:

db.wholesalers.find({ 
    "brands": { "$exists": true, "$type": 4 } 
}).snapshot().forEach(function(doc){ 
    db.wholesalers.updateOne(
        { "_id": doc._id },
        { "$set": { "brandsNetherlands": doc.brands } }
    );
});

虽然这对于小型集合来说是最佳的,但是大型集合的性能大大降低,因为循环遍历大型数据集并将每个请求的每个更新操作发送到服务器会导致计算损失。

Bulk() API可以帮助您提高性能,因为写入操作只会批量发送到服务器一次。效率得以实现,因为该方法不会向服务器发送每个写入请求(与 forEach() 循环中的当前更新语句一样),而是每1000个请求中只发送一次,从而使更新更多比现在更有效,更快。

使用上述相同的概念和 forEach() 循环来创建批次,我们可以按批量更新集合,如下所示。

在此演示中,MongoDB版本>= 2.6 and < 3.2中提供的 Bulk() API使用 initializeUnorderedBulkOp() 方法并行执行,如以及非确定性顺序,批量写入操作:

var bulk = db.wholesalers.initializeUnorderedBulkOp(),     counter = 0; //计数器以跟踪批量更新大小

db.wholesalers.find({ 
    "brands": { "$exists": true, "$type": 4 } 
}).snapshot().forEach(function(doc){ 

    bulk.find({ "_id": doc._id }).updateOne({ 
        "$set": { "brandsNetherlands": doc.brands } 
    });

    counter++; // increment counter
    if (counter % 1000 == 0) {
        bulk.execute(); // Execute per 1000 operations and re-initialize every 1000 update statements
        bulk = db.wholesalers.initializeUnorderedBulkOp();
    }
});

下一个示例适用于新的MongoDB版本3.2,该版本已弃用 Bulk() API,并使用 {{3}提供了一套更新的api }

它使用与上面相同的游标,但使用相同的 bulkWrite() 游标方法创建具有批量操作的数组,以将每个批量写入文档推送到数组。因为写入命令可以接受不超过1000次操作,所以需要将操作分组以进行最多1000次操作,并在循环达到1000次迭代时重新初始化数组:

var cursor = db.wholesalers.find({
         "brands": { "$exists": true, "$type": 4 } 
    }),
    bulkUpdateOps = [];

cursor.snapshot().forEach(function(doc){ 
    bulkUpdateOps.push({ 
        "updateOne": {
            "filter": { "_id": doc._id },
            "update": { "$set": { "brandsNetherlands": doc.brands } }
         }
    });

    if (bulkUpdateOps.length === 1000) {
        db.wholesalers.bulkWrite(bulkUpdateOps);
        bulkUpdateOps = [];
    }
});         

if (bulkUpdateOps.length > 0) { db.wholesalers.bulkWrite(bulkUpdateOps); }