2011-09-10 17 views
24

मैं एक उदाहरण खोज रहा हूं कि मैं एक मोंडोडीबी क्वेरी के परिणाम को नोडजेस क्लाइंट में कैसे स्ट्रीम कर सकता हूं। मुझे लगता है कि अब तक के सभी समाधान क्वेरी परिणाम को एक बार में पढ़ते हैं और फिर परिणाम को सर्वर पर वापस भेजते हैं।नोडजेस के साथ मोंगोडीबी क्वेरी परिणाम कैसे स्ट्रीम करें?

इसके बजाय, मैं (स्पष्ट रूप से) क्वेरी विधि में कॉलबैक की आपूर्ति करना चाहता हूं और मोंगोडीबी कॉल करता हूं कि जब परिणाम सेट का अगला हिस्सा उपलब्ध हो।

मैं मोंगोज़ को देख रहा हूं - क्या मुझे शायद एक अलग ड्राइवर का उपयोग करना चाहिए?

जनवरी

उत्तर

25

स्ट्रीमिंग नेवला में संस्करण 2.4.0 जो three months दिखाई दिया करने के बाद आप इस प्रश्न पोस्ट किया है में उपलब्ध हो गया:

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

अधिक सविस्तार उदाहरण उनकी documentation page पर पाया जा सकता।

+8

'मोंगोस: 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

आप उदाहरणों के बारे में सही हैं, स्रोत कोड में "उदाहरण" फ़ोल्डर के लिए आप उम्मीद कर सकते हैं। '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 में उपयोग करता है) कर्सर एपीआई है कि दूसरों का उल्लेख छोड़कर एक अच्छा धारा एपीआई (#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 इंटरफ़ेस लागू करता है, तो यह सभी उपहार (रोकें/फिर से शुरू आदि)

+1

मुझे दस्तावेज मिला है कि @Dan Milon http: // mongodb पर क्या संदर्भ दे रहा है। github.com/ वेबसाइट। यहां यह है [कुसररस्ट्रीम] (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

सर्वश्रेष्ठ उत्तर! और एक दस्तावेज़ लिंक के साथ! –

संबंधित मुद्दे