JavaScript在更新mongodb

时间:2019-05-03 05:18:10

标签: node.js mongodb mongoose sequelize.js

我正在尝试将数据之间同步到数据存储,源是mssql,目标是MongoDB。在此同步过程中,我遇到了内存堆错误。我不确定为什么会发生这种情况,我完全知道以下代码可能不是最好的,但是现在我只是想了解为什么分配错误会出现。

我正在用babel编译我的代码,在开发中我只使用babel-node。

try {
  const response = await sqlDataStore.findAll({
    attributes: ['id', 'Name'],
  });
  /* eslint no-restricted-syntax: 0 */
  for (const item of response) {
    /* eslint no-await-in-loop: 0 */
    await this.Model.updateOne({}, item, { upsert: true });
  }
} catch (err) {
  console.log(err);
}

如果我正确理解堆错误是由for循环引起的,那么这意味着每个await语句都缓存在内存中。我本来希望从内存中清除每个await语句,因为我没有将其分配给任何变量。

已更新:

很高兴由于另一则帖子,我已经找到了解决方案:Bulk upsert in MongoDB using mongoose

我的代码:

  const response = await sqlDataStore.findAll({
    attributes: ['id', 'Name'],
  });

  const bulkUpdate = response.map(doc => ({
    updateOne: {
      filter: { _id: doc.id },
      update: doc.dataValues,
      upsert: true,
    },
  }));

  this.Model.collection.bulkWrite(bulkUpdate);

如果有人正在使用此解决方案,则应记住,这也可能导致大量数据崩溃。其他职位提供的解决方案建议应在1000个存储桶中处理数据,直到每个文档都被更新/插入。

仅出于兴趣和技术上的理解,我将对我在第一个代码中确实做错了什么进行解释。

1 个答案:

答案 0 :(得分:0)

之所以得到这个,是因为您的函数调用堆栈没有释放,因为他们正在等待其他调用来完成其执行。

由于所有调用堆栈都阻塞了您的堆栈内存,因此在执行某些代码后,您将出现内存不足异常。

检查此链接: https://eslint.org/docs/rules/no-await-in-loop

您可以看到您的await呼叫在内存中被阻塞,以等待其他await完成,并且他们正在一次性向您返回值,这在您的代码中很糟糕。

实际上您是在进行同步通话,每个同步通话都在等待其他同步通话结束,最后,您的同步通话堆积在堆栈内存中,并且您遇到异常