Node.js - MongoDB原生查找所有文档

16

根据mongodb nodejs手册中的示例,我正在按如下方式查找数据库中的所有文档

mongo.Db.connect(mongoUri, function (err, db) {
    if (err) {
        console.log(err);
    } 
    else {
        db.collection('test').find().toArray(function(e, d) {
            console.log(d.length);
            db.close();
        });
    }
});

现在我注意到的是整个数据集被转换成了一个数组。随着数据集的增长,这将不是理想的方法。是否有任何方法可以流式传输数据,以便每次不必加载到内存中?

谢谢。

4个回答

21
最简单的方法是使用一个光标(reference):
var cursor = db.collection('test').find();

// Execute the each command, triggers for each document
cursor.each(function(err, item) {
    // If the item is null then the cursor is exhausted/empty and closed
    if(item == null) {
        db.close(); // you may not want to close the DB if you have more code....
        return;
    }
    // otherwise, do something with the item
});

如果您需要进行大量计算,您可能需要考虑是否使用Map-Reduce(reference),因为代码将在数据库服务器上执行,而不是本地执行。

2
谢谢你提出使用Map-Reduce的建议。我一直在思考这个问题,但是我不确定自己是否足够理解MongoDB上Map-Reduce的原理来解决我的问题。但我一定会在未来重新考虑这个方案。 - dopplesoldner

17

相对于循环方法,这是一种新的快速方式

const data = await db.collection('parkingSigns').find().toArray();
data // array with all the documents in the collection.

这种方法在处理五十万条记录时仍能保持快速吗? - Yusuf Khan
它对于最多50K条记录运行得非常快,不确定500k的情况,但应该比循环更快。 - TKdevlop

14
您可以通过在返回的游标上调用stream()方法来流式传输Node.js原生驱动程序查询的结果:
var stream = collection.find().stream();
stream.on('data', function(doc) {
    console.log(doc);
});
stream.on('error', function(err) {
    console.log(err);
});
stream.on('end', function() {
    console.log('All done!');
});

1
stream()和next()有什么区别? - Loveen Dyall

0

是否可以通过限制查询来解决问题?使用 db.collection.find().limit() 方法即可。该方法会在向服务器发送命令之前对限制条件进行解析,因此只会扫描限制范围内的数据。


我的应用程序实际上需要对数据进行一些数学计算,并返回最相似的文档。因此,我正在返回所有文档并在本地执行计算。现在,如果我可以在数据库本身上执行这些计算,那就太好了,但我不知道是否可能? - dopplesoldner

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接