如何使用nodejs流式传输MongoDB查询结果?

Jan*_*sen 30 streaming mongodb node.js

我一直在寻找一个如何将MongoDB查询的结果流式传输到nodejs客户端的示例.到目前为止我找到的所有解决方案似乎都会立即读取查询结果,然后将结果发送回服务器.

相反,我(显然)希望提供一个回调查询方法,并让MongoDB在结果集的下一个块可用时调用它.

我一直在看猫鼬 - 我应该使用不同的驱动程序吗?

一月

Dan*_*lon 29

node-mongodb-driver(每个mongoDB客户端在nodejs中使用的底层)除了其他人提到的游标API有一个很好的流API(#458).不幸的是我没有在其他地方找到它.

更新:有文档也是在这里.

它可以像这样使用:

var stream = collection.find().stream()
stream.on('error', function (err) {
  console.error(err)
})
stream.on('data', function (doc) {
  console.log(doc)
})
Run Code Online (Sandbox Code Playgroud)

它实际上实现了ReadableStream接口,所以它具有所有的好处(暂停/恢复等)


nab*_*nab 28

Mongoose中的流媒体版本在2.4.0版本中可用,该版本在您发布此问题三个月后出现:

Model.where('created').gte(twoWeeksAgo).stream().pipe(writeStream);
Run Code Online (Sandbox Code Playgroud)

可以在其文档页面上找到更详细的示例.

  • `Mongoose:在mongoose> = 4.5.0中不推荐使用Query.prototype.stream(),而是使用Query.prototype.cursor()代替` (11认同)

Gat*_* VP 10

mongoose它实际上不是"驱动程序",它实际上是围绕MongoDB驱动程序(node-mongodb-native)的ORM包装器.

要做你正在做的事情,看一下驱动程序.find.each方法.以下是示例中的一些代码:

// Find all records. find() returns a cursor
collection.find(function(err, cursor) {
  sys.puts("Printing docs from Cursor Each")
  cursor.each(function(err, doc) {
    if(doc != null) sys.puts("Doc from Each " + sys.inspect(doc));
  })                    
});
Run Code Online (Sandbox Code Playgroud)

要流式传输结果,您基本上将其替换sys.puts为"流"功能.不确定您打算如何流式传输结果.我想你可以做response.write() + response.flush(),但你可能也想结账socket.io.