- GitHub 仓库:Fundebug/loop-mongodb-big-collection
本文使用的编程语言是 Node.js,连接 MongoDB 的模块用的是mongoose。但是,本文介绍的方法适用于其他编程语言及其对应的 MongoDB 模块。
错误方法:find()
也许,在遍历 MongoDB 集合时,我们会这样写:
const Promise = require("bluebird");
function findAllMembers() {
return Member.find();
}
async function test() {
const members = await findAllMembers();
let N = 0;
await Promise.mapSeries(members, member => {
N++;
console.log(`name of the ${
N}th member: ${
member.name}`);
});
console.log(`loop all ${
N} members success`);
}
test();
注意,我们使用的是 Bluebird 的mapSeries而非map,members 数组中的元素是一个一个处理的。这样就够了吗?
当 Member 集合中的 document 不多时,比如只有 1000 个时,那确实没有问题。但是当 Member 集合中有 1000 万个 document 时,会发生什么呢?如下:
<--- Last few GCs --->
rt of marking 1770 ms) (average mu = 0.168, current mu = 0.025) finalize [5887:0x43127d0] 33672 ms: Mark-sweep 1398.3 (1425.2) -> 1398.0 (1425.7) MB, 1772.0 / 0.0 ms (+ 0.1 ms in 12 steps since start of marking, biggest step 0.0 ms, walltime since start of marking 1775 ms) (average mu =