之前在计算一些得分的时候,为了方便使用view 实时计算,后来随着数据量的增加,计算耗时持续上涨,不得不把view 持久化为collection。
最开始我再写入的时候是这样实现的:
const list=await aggr.pipeline() for (let j = 0; j < list.length; j++) { const record = list[i] // 幂等 await this.ctx.model.ActionRate.updateOne({ user: record.user, }, record, { upsert: true }); }
后来执行的时候,发现每次执行写入,耗时都挺久的,想优化下,于是发现了bulkWrite这个非常不错的方法。用如下:
const bulkOps = list.map(record => ({ updateOne: { filter: { user: record.user }, update: { $set: record }, upsert: true, }, })); // 执行批量操作 const result = await this.ctx.model.ActionRate.bulkWrite(bulkOps); console.log(`${result.modifiedCount} documents modified, ${result.upsertedCount} documents upserted`);
耗时直接从100s变成了4.4s,非常丝滑。