【发布时间】:2019-09-21 15:20:52
【问题描述】:
我正在尝试在数据存储之间同步数据,源是 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 个桶中处理数据。
仅出于兴趣和技术理解,我希望能解释一下我在第一个代码中到底做错了什么。
【问题讨论】:
-
只是为了确定,代码在第一个 SQL 查询中运行良好吗?也就是说,是不是引入的数据量太大了?
-
是的,sql查询绝对没问题,数据量也不大,只有2401行。
-
嗨,我知道操作被延迟了,但这不是我的问题,问题是它们是否确实存储在内存中,以及即使我没有将响应存储在任何内容中,这是否是预期的行为变量。
-
我猜这是因为您的执行完全阻塞了下一次执行,并且将在内存中直到您的整个执行完成。检查我分享的链接。
标签: node.js mongodb mongoose sequelize.js