node+mongoose ,利用 pm2 管理项目,内存限制 512MB 。业务是查询记录,然后导出 excel 。目前是手动将万条数据 id ,1000 条一组跑循环查询,放入数组,最后拿数组生成文件。但每次都内存超出,项目重启了。
1 Dnlyao OP let ids = [] let total = await TradeRecord.find(conditions).select('id').sort({'tradeAt': -1}) for (let item of total) { ids.push(item._id) } for (let index = 1; index <= Math.floor(ids.length / 10) + 1; index++) { let tradids = [] let i = index - 1 > 0 ? (index - 1) * 10 : 0 if ((index * 10) < ids.length) { tradids = ids.slice(i, index * 10) } else { tradids = ids.slice(i) } if (tradids.length > 0) { let ret = await TradeRecord.find({_id: {$in: tradids}}) .select('device organization restaurant user deploySite consumeInterval amount mainAccountAmount subsidyAmount giveFreeAmount balance subsidyBalance giveFreeBalance tradeAt sn deviceSerial subAccount supermarketConsume payMethod consumeType consumePayMethod deviceMode ') .populate('organization', 'name') .populate('restaurant', 'name') .populate('deploySite', 'name') .populate({ path: 'user', select: 'department name type jobNumber cardUid fingerprint', populate: {path: 'department', select: 'name'} }) rowsbase.push(...ret) } } } 代码如上 |
![]() | 2 617953997 2022-04-08 10:28:50 +08:00 流式查询 + 流式写入 |
![]() | 3 yousabuk 2022-04-08 10:52:46 +08:00 via iPhone 查完 1000 条,写文件,再查一下个 1000 条,写文件。 再不行就每次 100 条,50 条…… 看不懂这个代码,但是小内存下处理就是这么个流程。 |
4 micean 2022-04-08 11:01:28 +08:00 #3+1 每查 1000 条写在 csv 尾部就行了 |
5 paopjian 2022-04-08 11:04:19 +08:00 内存有限制写入 excel 是不是炸内存了,写成 csv 试一下? |
6 Dnlyao OP 流程是 let row =[] 先查询 1000 条数据 再 push 进 row ,再循环下去。未到写入文件,就爆内存了 |
![]() | 7 twing37 2022-04-08 11:27:56 +08:00 有没有可能流程是 使用 stream, send -> limit buffer -> rev 呢? |
![]() | 8 4771314 2022-04-08 11:30:38 +08:00 分片处理或者使用 stream 的方式向 excel 中追加数据,最后将 Excel 导出,应该可以解决 |
9 Dnlyao OP 感谢各位回复,我去尝试一下。 |
10 INCerry 2022-04-08 17:03:08 +08:00 应该是要复用内存的 |
12 Dnlyao OP 用了 .cursor() eachAsync 还是不行,内存控制不住 |
![]() | 13 snoy 2022-04-09 16:50:34 +08:00 姿势不对,我这个可以 [email protected]:gogogo1024/mongodbStreamToCSV.git |