Подтвердить что ты не робот

Как передать результаты запросов MongoDB с помощью nodejs?

Я искал пример того, как я могу передать результат запроса MongoDB клиенту nodejs. Все решения, которые я нашел до сих пор, похоже, сразу читают результат запроса, а затем отправляют результат обратно на сервер.

Вместо этого я (очевидно) хотел бы предоставить обратный вызов методу запроса и вызвать MongoDB, когда доступен следующий фрагмент результирующего набора.

Я смотрел мангуст - должен ли я использовать другой драйвер?

Jan

4b9b3361

Ответ 1

Потоковая передача в Mongoose стала доступна в версии 2.4.0, которая появилась три месяца после того, как вы разместили этот вопрос:

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

Более подробные примеры можно найти на странице .

Ответ 2

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

Он фактически реализует интерфейс ReadableStream, поэтому он имеет все полезные свойства (пауза/возобновление и т.д.)

Ответ 3

mongoose на самом деле не является "драйвером", он фактически является оберткой ORM вокруг драйвера MongoDB (node-mongodb-native).

Чтобы сделать то, что вы делаете, взгляните на метод драйвера .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.

Ответ 4

Вот решение, которое я нашел (пожалуйста, поправьте меня всем, если это неправильный способ сделать это): (Также извините за плохое кодирование - слишком поздно для меня сейчас, чтобы отменить это)

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

Ответ 5

Я сам изучал потоки mongodb, хотя у меня нет полного ответа, который вы ищете, у меня есть его часть. Вы можете настроить поток socket.io

это использует javascript socket.io и socket.io-streaming, доступные в NPM, также mongodb для базы данных, потому что использование базы данных 40-летнего возраста, которая имеет проблемы, является неправильным, время для модернизации также 40-летнего БД - это SQL, а SQL - нет делай потоки, насколько мне известно

Таким образом, хотя вы спрашивали только о данных, передаваемых с сервера на клиент, я также хочу, чтобы в ответе я получал информацию от клиента к серверу, потому что НИКОГДА не могу найти ее в любом месте при поиске, и я хотел настроить одно место с элементами отправки и получения через поток чтобы каждый мог быстро освоиться.

клиентская сторона отправляет данные на сервер посредством потоковой передачи

stream = ss.createStream();
blobstream=ss.createBlobReadStream(data);
blobstream.pipe(stream);
ss(socket).emit('data.stream',stream,{},function(err,successful_db_insert_id){
 //if you get back the id it went into the db and everything worked
});

сервер получает поток со стороны клиента и затем отвечает, когда все готово

ss(socket).on('data.stream.out',function(stream,o,c){
 buffer=[];
 stream.on('data',function(chunk){buffer.push(chunk);});
 stream.on('end',function(){
  buffer=Buffer.concat(buffer);
  db.insert(buffer,function(err,res){
   res=insertedId[0];
   c(null,res);
  });
 });
});

//Это вторая половина этой выборки данных и потоковой передачи на клиент

клиентская сторона запрашивает и получает потоковые данные с сервера

stream=ss.createStream();
binarystring='';
stream.on('data',function(chunk){ 
 for(var I=0;i<chunk.length;i++){
  binarystring+=String.fromCharCode(chunk[i]); 
 }
});
stream.on('end',function(){ data=window.btoa(binarystring); c(null,data); });
ss(socket).emit('data.stream.get,stream,o,c);

ответ на запрос потоковой передачи данных на стороне сервера

ss(socket).on('data.stream.get',function(stream,o,c){
 stream.on('end',function(){
  c(null,true);
 });
 db.find().stream().pipe(stream);
});

Самый последний - единственный, где я просто вытаскиваю его из задницы, потому что я еще не пробовал, но это должно сработать. На самом деле я делаю что-то подобное, но я записываю файл на жесткий диск, а затем использую fs.createReadStream для потоковой передачи его клиенту. Так что не уверен, если 100%, но из того, что я прочитал, должно быть, я вернусь к вам, как только я проверю это.

Ps, кто-нибудь хочет меня обидеть из-за моей разговорной манеры говорить, я канадец, и я люблю говорить "ах", подойди ко мне со своими объятиями и ударишь братан/сестренку: D