node.js MongoDB cursor.toArray() 的替代方法

Alternatives to MongoDB cursor.toArray() in node.js

我目前正在使用 MongoDB 游标的 toArray() 函数将数据库结果转换为数组:

run = true;
count = 0;
var start = process.hrtime();
db.collection.find({}, {limit: 2000}).toArray(function(err, docs){
  var diff = process.hrtime(start);
  run = false;
  socket.emit('result', {
    result: docs,
    time: diff[0] * 1000 + diff[1] / 1000000,
    ticks: count
  });
  if(err) console.log(err);
});

这个操作在我的电脑上大约需要 7 毫秒。如果我删除 .toArray() 函数,则该操作大约需要 0.15 毫秒。当然这行不通,因为我需要转发数据,但我想知道这个函数在做什么,因为它需要这么长时间?数据库中的每个文档仅由 4 个数字组成。

最后我希望 运行 在一个更小的处理器上实现这个,比如 Raspberry Pi,这里的操作是从数据库中获取 500 个文档并将其转换为阵列大约需要 230 毫秒。这对我来说似乎很多。还是我期待太多了?

是否有其他方法可以在不使用 toArray() 的情况下从数据库中获取数据?

我注意到的另一件事是,整个 Node 应用程序在获取数据库结果时速度明显变慢。我创建了一个简单的间隔函数,它应该每 1 毫秒递增一次计数值:

setInterval(function(){
  if(run) count++;
}, 1);

然后我希望计数值与时间几乎相同,但在我的计算机上,对于 16 毫秒的时间,计数值为 3 或 4。在 Raspberry Pi 上,计数值为从未增加。什么占用了这么多 CPU 的使用量?监视器告诉我我的计算机使用了 27% CPU 而 Raspberry Pi 使用了 92% CPU 和 11% RAM,当被要求重复 运行 数据库查询时。

我知道有很多问题。非常感谢任何帮助或解释。我还是 Node 的新手 MongoDB.

db.collection.find() returns一个游标,不是结果,打开游标还挺快的。

一旦您开始读取游标(使用.toArray()或使用.each() or .next()遍历它),实际文档就会从数据库传输到你的客户。该操作占用了大部分时间。

我怀疑使用 .each()/.next()(而不是 .toArray(),它在后台使用这两者之一)会大大提高性能,但您总是可以尝试(谁知道) .由于 .toArray() 将读取内存中的所有内容,这可能是值得的,尽管听起来您的数据集没有那么大。

我真的认为 Raspberry Pi(尤其是模型 1)上的 MongoDB 效果不佳。如果您不太依赖 MongoDB 查询功能,您应该考虑使用替代数据存储。甚至可能是内存存储(500 个文档乘以 4 个数字听起来并不需要大量 RAM)。