在MongoDB中使用mongoose批量插入多个集合

时间:2017-10-12 08:31:52

标签: node.js mongodb mongoose bulkinsert mongoose-populate

我有2个收藏集(datametaData

data架构是

{
_id: ......,
name: ......, //not unique
mobile: ......, // unique or null
email: ......, // unique or null
uniqueId: ......, // unique or null
}

插入

至少需要一个唯一数据

metaData架构是

{
_id: ......,
dataId: ......,//refrence from _id of data collection
key: ......,
value: ......
}

JSON数组来自客户端

[{
  name: "abc",
  mobile: 9999999999,
  mData: {
    c1: 123,
    c2: "xyz"
  }
},
{
  name: "qwerty",
  email: 'qwerty@mail.com',
  mData: {
    c1: 123,
    c2: "zxc"
  }
}
......
]

我正在遍历数组并将两个集合中的每一个插入到MongoDB中。

let Bulk = Data.collection.initializeUnorderedBulkOp();
dataArr.forEach(function(item) {
  let data = service.generateData(item);
  // data.query: {mobile: ..., email: ..., uniqueId: ...}
  // if value exists then keys is also exists for mobile, email, uniqueId in query
  Bulk.find(data.query).upsert().updateOne(data.doc);
});
Bulk.execute((e, d) => {
  let metaBulk = MetaData.collection.initializeOrderedBulkOp();
  let length = dataArr.length;
  dataArr.forEach(function(data) {
    Data.findOne(data.query).exec(function(err, data) {
      length--;      
      for(let key in data["mData"]) {
        let value = data["mData"][key] || "";
        let mData = service.generateMdata(key, value, data._id);
        metaBulk.find(mData.query).upsert().updateOne(mData.doc);
      }
      if(length == 0) {
        metaBulk.execute();
      }
    });
  });
});

我的解决方案现在正常运行,但是花了很多时间来迭代data集合来查找metaData集合的ID。

我需要一种将数据批量插入MongoDB而无需查询数据ID的方法。是否有任何选项可以在单个查询中使用mongoose对多个集合执行批量upsert。

2 个答案:

答案 0 :(得分:1)

在您的方案的单个命令中不会更新多个集合。在您的情况下,如果您可以在父集合中包含元数据数组,则可以使用updateMany()使用单个命令插入数据。 MongoDB还支持通过db.collection.insertMany()批量插入。

db.data.insertMany( [{ name: "abc",mobile: 9999999999, mData: { c1: 123, c2: "xyz"} },
                                            {name: "qwerty",email: 'qwerty@mail.com',mData: { c1: 123, c2: "zxc" }}]);

此外,您也可以使用db.collection.bulkWrite()

答案 1 :(得分:-1)

我认为你能做的是:

async.each(jsonArray, function(jsonData,callback){
  //first insert data in data schema
  var data = new data(jsonData);
  data.save(function(err){
    if err throw err;
    //then you save the data in metaData collection
    async.each(jsonData.mData, function(metadata, callback2){
      var metaDataObj = new metaData(metadata);
      metaDataObj.dataId = data._id;
      metaDataObj.save(function(err){
       callback2();
      });
    }, function(err, results1){
      callback();
    });
  });
}, function(err, results){
   console.log('Data is saved');
});