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 |