猫鼬:更新大量数据

时间:2018-03-23 11:44:11

标签: node.js mongodb mongoose bigdata

所以,这是我的问题。我有两个集合(coll1,coll2),其中包含大约150万个具有相同字段的文档。他们有超过95%的文档是共同的,但有些coll1文档的电子邮件填充不为null,而coll2有更多的文档。

我想要的最终集合是coll2,但是带有coll1的电子邮件。

这是我的表现:

 const options = {
  socketTimeoutMS: 0,
  keepAlive: true,
  reconnectTries: 30,
};
mongoose.connect(`mongodb://localhost:27017/coll1`, options);

const Coll1Model = mongoose.model(coll, collSchema);

Coll1Model.find({ email: { $ne: '' } })
  .select({ id: 1, email: 1, _id: 0 })
  .then((result) => {
    const Coll2Model = mongoose.model(coll2, collSchema);

    const bulk = Coll2Model.collection.initializeUnorderedBulkOp();
    // c is about 390k
    const c = result.length;
    for (let i = 0; i < c; i += 1) {
      bulk.find({ id: result[i].id }).updateOne({ $set: { email: result[i].email } });
    }
    bulk
      .execute()
      .then((result) => {
        console.log(result);
        console.log('End', new Date());
      })
      .catch((err) => {
        console.log(err);
        console.log('End', new Date());
      });
  })
  .catch((err) => {
    console.log('Error', err);
  });

我遇到的问题是它太长而且太耗费资源(大约1小时30分,20%,cpu介于60和80%之间)

我是MongoDB和mongoose的专家,所以如果有人有这个想法,我会很高兴这样做。

1 个答案:

答案 0 :(得分:1)

我设法用索引将时间从4-5小时减少到2-3分钟。

db.coll2.createIndex({id: 1}, function(err, col) {
  var bulk = db.coll2.initializeUnorderedBulkOp();

  db.coll1.find({ email: { $ne: '' } }).forEach(function(data) {
    bulk.find({ id: data.id }).updateOne({ $set: { email: data.email } 
    });
  });

  bulk.execute();
}

在命令行中执行:mongo mydb update.js