2011-09-10 49 views
24

我一直在尋找一個如何將一個MongoDB查詢的結果流到一個nodejs客戶端的例子。到目前爲止,我發現的所有解決方案似乎都是一次讀取查詢結果,然後將結果發送回服務器。如何使用nodejs流式傳輸MongoDB查詢結果?

相反,我會(顯然)喜歡爲查詢方法提供回調,並在結果集的下一個塊可用時讓MongoDB調用它。

我一直在看貓鼬 - 我應該可能使用不同的驅動程序?

回答

25

流在貓鼬成了2.4.0版本,這似乎three months你已經張貼了這個問題後可用:

Model.where('created').gte(twoWeeksAgo).stream().pipe(writeStream); 

更詳細闡述的例子可以在他們的documentation page找到。

+8

'Mongoose:Query.prototype.stream()在mongoose> = 4.5.0中被棄用,使用Query.prototype.cursor()來代替' –

9

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)); 
    })      
}); 

要流的結果,你基本上代替該sys.puts你的「流」功能。不知道您計劃如何傳輸結果。我認爲你可以做response.write() + response.flush(),但你可能也想結賬socket.io

+1

謝謝 - 司機的問題,我發現了昨天。我期待的查找/光標解決方案,但卻很難找到例子。大多數做一個查找,然後docs.foreach(...) –

+0

更新:其實,我沒有得到這個以你描述的方式工作。我所要做的就是創建一個EventEmitter,將響應流和來自後端的數據流粘合在一起。 –

+0

你對這些例子是正確的,最好你可以希望的是源代碼中的「examples」文件夾。 'EventEmitter'也聽起來正確。如果你有一個很好的例子,我們可以更詳細地更新這個答案。 –

2

這裏是我找到的解決方法(請糾正我,任何人如果thatis錯誤的方式做到這一點): (也原諒壞的編碼 - 太晚了,我現在要美化這一點)

var sys = require('sys') 
var http = require("http"); 

var Db = require('/usr/local/src/npm/node_modules/mongodb/lib/mongodb').Db, 
    Connection = require('/usr/local/src/npm/node_modules/mongodb/lib/mongodb').Connection, 
    Collection = require('/usr/local/src/npm/node_modules/mongodb/lib/mongodb').Collection, 
    Server = require('/usr/local/src/npm/node_modules/mongodb/lib/mongodb').Server; 

var db = new Db('test', new Server('localhost',Connection.DEFAULT_PORT , {})); 

var products; 

db.open(function (error, client) { 
    if (error) throw error; 
    products = new Collection(client, 'products'); 
}); 

function ProductReader(collection) { 
     this.collection = collection; 
} 

ProductReader.prototype = new process.EventEmitter(); 

ProductReader.prototype.do = function() { 
     var self = this; 

     this.collection.find(function(err, cursor) { 
       if (err) { 
         self.emit('e1'); 
         return; 

       } 
       sys.puts("Printing docs from Cursor Each"); 

       self.emit('start'); 
       cursor.each(function(err, doc) { 
         if (!err) { 
           self.emit('e2'); 
           self.emit('end'); 
           return; 
         } 

         if(doc != null) { 
           sys.puts("doc:" + doc.name); 
           self.emit('doc',doc); 
         } else { 
           self.emit('end'); 
         } 
       }) 
     }); 
}; 
http.createServer(function(req,res){ 
     pr = new ProductReader(products); 
     pr.on('e1',function(){ 
       sys.puts("E1"); 
       res.writeHead(400,{"Content-Type": "text/plain"}); 
       res.write("e1 occurred\n"); 
       res.end(); 
     }); 
     pr.on('e2',function(){ 
       sys.puts("E2"); 
       res.write("ERROR\n"); 
     }); 

     pr.on('start',function(){ 
       sys.puts("START"); 
       res.writeHead(200,{"Content-Type": "text/plain"}); 
       res.write("<products>\n"); 
     }); 

     pr.on('doc',function(doc){ 
       sys.puts("A DOCUMENT" + doc.name); 
       res.write("<product><name>" + doc.name + "</name></product>\n"); 
     }); 

     pr.on('end',function(){ 
       sys.puts("END"); 
       res.write("</products>"); 
       res.end(); 
     }); 

     pr.do(); 

    }).listen(8000); 
22

node-mongodb-driver(每個mongoDB客戶端在nodejs中使用的基礎層)除了其他人提到的遊標API有一個漂亮的流API(#458)。不幸的是,我沒有在其他地方找到它。

更新:there are docshere

它可以像這樣使用:

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

它實際上是實現了ReadableStream接口,因此它具有所有的好東西(暫停/恢復等)

+1

我發現了文檔以指出@Dan Milon在http:// mongodb中提到的內容。 github.com/網站。這裏是[CusrsorStream](http://mongodb.github.com/node-mongodb-native/api-generated/cursorstream.html) – ilikeopensource

+0

甚至不知道這存在!謝謝! [mongodb.github.com/node-mongodb-native](http://mongodb.github.com/node-mongodb-native)即爲此事。 –

+3

最佳答案!並與文檔鏈接! –