有条件地更新/插入和添加到阵列

时间:2017-07-23 12:08:55

标签: javascript node.js mongodb mongoose

我的.tsv文件包含一些订单信息。重拍到我的剧本后,我得到了这个。

[{"order":"5974842dfb458819244adbf7","name":"Сергей Климов","email":"wordkontent@gmail.com"},
{"order":"5974842dfb458819244adbf8","name":"Сушков А.В.","email":"mail@wwwcenter.ru"},
{"order":"5974842dfb458819244adbf9","name":"Виталий","email":"wawe2012@mail.ru"},
...
and so on

我有一个猫鼬形象。

var ClientSchema = mongoose.Schema({
  name:{
    type: String
  },
  email:{
    type: String,
    unique : true,
    required: true,
    index: true
  },
  forums:{
    type: String
  },
  other:{
    type: String
  },
  status:{
    type: Number,
    default: 3
  },
  subscribed:{
    type: Boolean,
    default: true
  },
  clienturl:{
    type: String  
  },
  orders:{
    type: [String]
  }
});

clienturl是密码8个字符长度,由函数生成。

module.exports.arrayClientSave = function(clientsArray,callback){
  let newClientsArray = clientsArray
    .map(function(x) {
      var randomstring = Math.random().toString(36).slice(-8);
      x.clienturl = randomstring;
      return x;
    });
  console.log(newClientsArray);
  Client.update( ??? , callback );
}

但我不知道如何进行更新。如果电子邮件已经存在推送订单数组,但不会重写所有其他字段。但如果电子邮件不存在 - 使用clienturl保存新用户等等。谢谢!

1 个答案:

答案 0 :(得分:1)

处理此问题的最佳方法可能是通过.bulkWrite(),这是一种MongoDB方法,用于在“单个”请求中使用“单个”响应发送“多个操作”。这反过来需要控制每个“循环”项目的问题和响应中的异步函数。

module.exports.arrayClientSave = function(clientsArray,callback){
  let newClientsArray = clientsArray
    .map(x => {
      var randomstring = Math.random().toString(36).slice(-8);
      x.clienturl = randomstring;
      return x;
    });
    console.log(newClientsArray);

    let ops = newClientsArray.map( x => (
      { "updateOne": {
        "filter": { "email": x.email },
        "update": {
          "$addToSet": { "orders": x.order },
          "$setOnInsert": {
            "name": x.name,
            "clientUrl": x.clienturl
          }
        },
        "upsert": true
      }}
    ));

    Client.bulkWrite(ops,callback);
};

主要的想法是使用MongoDB的"upsert"功能来驱动“创建或更新”功能。 $addToSet仅将"orders"属性信息附加到尚未存在的数组的位置,而$setOnInsert实际上仅在操作实际为"upsert"

同样通过在.bulkWrite()中应用它,当与支持它的MongoDB服务器通信时,这变为“单异步调用”,并且是任何大于或等于MongoDB 2.6的版本。

然而,特定.bulkWrite() API的要点是API本身将“检测”连接的服务器是否实际支持“批量”操作。如果没有,则“降级”为单个“异步”调用,而不是一个批次。但这是由“驱动程序”控制的,它仍然会与您的代码进行交互,就像它实际上是一个请求和响应一样。

这意味着处理“异步循环”的所有困难实际上都是在驱动程序软件本身中处理的。要么被支持的方法否定,要么以一种简化代码使用的方式“模拟”。