我一直在尋找一個如何將一個MongoDB查詢的結果流到一個nodejs客戶端的例子。到目前爲止,我發現的所有解決方案似乎都是一次讀取查詢結果,然後將結果發送回服務器。如何使用nodejs流式傳輸MongoDB查詢結果?
相反,我會(顯然)喜歡爲查詢方法提供回調,並在結果集的下一個塊可用時讓MongoDB調用它。
我一直在看貓鼬 - 我應該可能使用不同的驅動程序?
月
我一直在尋找一個如何將一個MongoDB查詢的結果流到一個nodejs客戶端的例子。到目前爲止,我發現的所有解決方案似乎都是一次讀取查詢結果,然後將結果發送回服務器。如何使用nodejs流式傳輸MongoDB查詢結果?
相反,我會(顯然)喜歡爲查詢方法提供回調,並在結果集的下一個塊可用時讓MongoDB調用它。
我一直在看貓鼬 - 我應該可能使用不同的驅動程序?
月
流在貓鼬成了2.4.0版本,這似乎three months你已經張貼了這個問題後可用:
Model.where('created').gte(twoWeeksAgo).stream().pipe(writeStream);
更詳細闡述的例子可以在他們的documentation page找到。
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
。
謝謝 - 司機的問題,我發現了昨天。我期待的查找/光標解決方案,但卻很難找到例子。大多數做一個查找,然後docs.foreach(...) –
更新:其實,我沒有得到這個以你描述的方式工作。我所要做的就是創建一個EventEmitter,將響應流和來自後端的數據流粘合在一起。 –
你對這些例子是正確的,最好你可以希望的是源代碼中的「examples」文件夾。 'EventEmitter'也聽起來正確。如果你有一個很好的例子,我們可以更詳細地更新這個答案。 –
這裏是我找到的解決方法(請糾正我,任何人如果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);
node-mongodb-driver
(每個mongoDB客戶端在nodejs中使用的基礎層)除了其他人提到的遊標API有一個漂亮的流API(#458)。不幸的是,我沒有在其他地方找到它。
更新:there are docs也here。
它可以像這樣使用:
var stream = collection.find().stream()
stream.on('error', function (err) {
console.error(err)
})
stream.on('data', function (doc) {
console.log(doc)
})
它實際上是實現了ReadableStream接口,因此它具有所有的好東西(暫停/恢復等)
我發現了文檔以指出@Dan Milon在http:// mongodb中提到的內容。 github.com/網站。這裏是[CusrsorStream](http://mongodb.github.com/node-mongodb-native/api-generated/cursorstream.html) – ilikeopensource
甚至不知道這存在!謝謝! [mongodb.github.com/node-mongodb-native](http://mongodb.github.com/node-mongodb-native)即爲此事。 –
最佳答案!並與文檔鏈接! –
'Mongoose:Query.prototype.stream()在mongoose> = 4.5.0中被棄用,使用Query.prototype.cursor()來代替' –