В настоящее время я работаю над проектом NodeJS / Mongo, в котором мне нужно вытащить все документы из коллекции. В настоящее время у меня написан следующий код:

var Db = require('mongodb').Db,
    MongoClient = require('mongodb').MongoClient,
    Server = require('mongodb').Server,
    ReplSetServers = require('mongodb').ReplSetServers,
    ObjectID = require('mongodb').ObjectID,
    Binary = require('mongodb').Binary,
    GridStore = require('mongodb').GridStore,
    Grid = require('mongodb').Grid,
    Code = require('mongodb').Code,
    assert = require('assert');

var server = new Server('[server]', 27017);

var authDB = new Db('admin', server);
var DB1250 = new Db('1250', server); 

var findDocuments = function (callback) {
    authDB.authenticate("Username", "Password");
    DB1250.open(function (error, db) {
        if (error) {
            console.log(error);
        }
        else {
            console.log("successfully accessed: ", db);
            callback;
            var cursor = db.collection('Patients').find();
            console.log('cursor ', cursor);
            cursor.forEach(function (error, document) {
                if (error) {
                    console.log('Document does not exist. Error: ', error);
                }
                else {                        
                    console.log('Document: ', document);
                }
            });
        }
    });
};

findDocuments(function (data) {

});

Я могу пройти аутентификацию / подключиться к серверу, подключиться к БД и подключиться к коллекции. Когда я вхожу в цикл forEach для перебора всех документов, я продолжаю получать сообщение об ошибке «Обратный вызов не является функцией». Вы, ребята, видите, что я делаю не так?

0
CodePull 6 Сен 2016 в 18:19

3 ответа

Лучший ответ

Вот решение, которое я придумал после использования Mongoose:

var Db = require('mongodb').Db,
    MongoClient = require('mongodb').MongoClient,
    Server = require('mongodb').Server,
    ReplSetServers = require('mongodb').ReplSetServers,
    ObjectID = require('mongodb').ObjectID,
    Binary = require('mongodb').Binary,
    GridStore = require('mongodb').GridStore,
    Grid = require('mongodb').Grid,
    Code = require('mongodb').Code,
    Mongoose = require('mongoose'); 
    assert = require('assert');    

var findDocuments = function (callback) {
    var options = { server: { socketOptions: { keepAlive: 1000 } } };

    var connectionString = 'mongodb://username:password@server:27017/admin';

    // Connected handler
    Mongoose.connect(connectionString, function (err) {

        var db = Mongoose.connection.useDb('db'); 
        var collection = db.collection("collection");           

        collection.find().stream()
            .on('data', function (document) {
                console.log(document);
            })
            .on('error', function (err) {
                // handle error
                console.log(err);
            })
            .on('end', function () {
                // final callback
            });
    });

    // Error handler
    Mongoose.connection.on('error', function (err) {
        console.log(err);
    });

    // Reconnect when closed
    Mongoose.connection.on('disconnected', function () {
        self.connectToDatabase();
    });

};

findDocuments(function () {
    db.close();
});
0
CodePull 6 Сен 2016 в 20:43

cursor.forEach() - асинхронная операция, но ничего не возвращает. Так что вам не следует делать db.close() или что-то подобное ниже линии где-то синхронно.

Кроме; Я не уверен, на какую версию драйвера узла вы ссылаетесь, но в последних версиях, таких как v3 + cursor.forEach(), не выполняется обратный вызов первого типа с ошибкой, как тот, который вы используете в своем коде. Потребуется «итератор» и обратный вызов «end», например:

cursor.forEach(doc => console.log(doc),
               err => err ? console.log(err)
                          : db.close())

Таким образом, приведенный выше код будет работать нормально, повторяя и обрабатывая документы один за другим по мере их появления, не дожидаясь, пока все они будут извлечены в память.

0
Redu 30 Мар 2018 в 17:48

Я считаю, что курсор, который у вас там, не преобразован в массив, поэтому forEach не является допустимым методом. Возможно, вы ищете eachAsync, который будет ждать возврата запроса перед повторением .

В качестве альтернативы вы можете дождаться разрешения обещания запроса, то есть:

cursor.then(docs => docs.forEach(callback));

Что я лично считаю немного яснее.

1
broguinn 6 Сен 2016 в 15:25