我目前正在研究一个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) {
});
我能够验证/连接到服务器,连接到DB,并连接到集合。当我进入forEach循环遍历所有文档时,我一直得到错误"Callback不是一个函数"。你们能看出我哪里做错了吗?
我认为您在那里的游标尚未解析为数组,因此forEach
不是有效方法。您可能正在寻找eachAsync,它将在迭代之前等待查询返回。
或者,您可以等待查询承诺解析,即:
cursor.then(docs => docs.forEach(callback));
我个人觉得更清晰一些
以下是我使用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();
});
cursor.forEach()
是一个异步操作,但不返回任何值。所以你不应该同步地在db.close()
或类似的线下面的某处。
除了;我不确定您指的是哪个版本的节点驱动程序,但在最近的版本中,如v3+ cursor.forEach()
不会像您在代码中使用的那样采取错误第一类型回调。它将接受一个"迭代器"和一个"end"回调,如;
cursor.forEach(doc => console.log(doc),
err => err ? console.log(err)
: db.close())
因此,上面的代码将正常工作,迭代和处理文档一个接一个地出现,而不是等待,直到所有的文档都被检索到内存。