MongoDB和JavaScript堆内存不足

时间:2018-01-04 12:31:07

标签: javascript node.js mongodb out-of-memory

遥测表中的数据大小是巨大的。所以,我得到“JavaScript堆内存不足”的错误。 我该如何克服这个错误?

const aloUrl = `mongodb://${userName}:${pwd}@${host}:${port}/${dbName}`;
MongoClient.connect(aloUrl, function(err, client) {
if (err) {
return console.log('ERROR:: ', err);
}
console.log("INFO:: OK");
const db = client.db(dbName);

var arr = db.collection('endpoint').find({provider:"KMR"}).map(e => e._id).toArray((err, result) => {
    if (err){

        console.log("ERROR", err)
    }

        var son = db.collection('telemetry').find({endpoint: {$in: result}}).toArray().then(arr =>{

            console.log("Let's start to party")
            for (let i = 0; i < 10; i++) {
                console.log("\t" + arr[i]._id)
            }

        }).catch(e => {

            console.log(`ERROR::${e}`)
        })

})
});

3 个答案:

答案 0 :(得分:0)

来自mongodb docs,

  

toArray()方法返回一个包含所有文档的数组   从游标。该方法完全迭代光标,加载所有   文件进入RAM并耗尽光标

因此,您应该使用toArraynext(或其他一些不会一次性将所有内容加载到RAM中的方法)来代替调用forEach,以便迭代元素一个接一个。

例如,要打印您的遥测收集ONE BY ONE中的所有文件,您可以这样做,

db.collection('telemetry')
    .find({
        endpoint: {
            $in: result
        }
    })
    .forEach((document) => {
        console.log(document)
    });

答案 1 :(得分:0)

我建议您使用forEach而不是toArray来获取和加载w / o耗尽。

答案 2 :(得分:0)

对于大数据,总是建议流(它是通过mongo中的光标实现的)。

  

$ lookup是MongoDB 3.2中的新功能。它对同一数据库中的未整数集合执行左外连接,以便从“已连接”集合中过滤文档以进行处理。

您可以查看aggregation pipeline for mongo

使用聚合更新您的代码。

var MongoClient = require('mongodb').MongoClient;
// Connection URL
const aloUrl    = `mongodb://${userName}:${pwd}@${host}:${port}/${dbName}`;
MongoClient.connect(aloUrl, function (err, client) {
    console.log("INFO:: OK");
    const db   = client.db(dbName);
    const col  = db.collection('endpoint');
    var cursor = col.aggregate([
        {
            $match: {provider: "KMR"}
        },
        {
            $lookup:
                {
                    from        : "telemetry",
                    localField  : "_id",
                    foreignField: "endpoint",
                    as          : "telemetry"
                }
        }
    ]);
    console.log("Let's start to party")
    cursor.on('data', function (data) {
        console.log("\t" + data._id)
    });
    cursor.on('end', function () {
        console.log("Done ");
    });
});