Node.js重用MongoDB引用

我无法理解node.js。

例如,MongoDB访问,这是我得到(mydb.js):

var mongodb = require('mongodb'), server = new mongodb.Server('staff.mongohq.com', 10030, { auto_reconnect: true }), db = new mongodb.Db('mydb', server); function authenticateAndGo(db, handle) { db.authenticate('username', 'password', function(err) { if (err) { console.log(err); return; } console.log('Database user authenticated'); var collection = new mongodb.Collection(db, 'test'); handle(collection); }); } function query(handle) { db.open(function(err, db) { if( err ) { console.log(err); return; } console.log('Database connected'); authenticateAndGo(db, handle); }); }; exports.query = query; 

所以,如果我想稍后使用它,我会的

 var mydb = require('./mydb'); mydb.query(function(collection) { collection.find({}, { limit: 10 }).toArray(function(err, docs) { console.log(docs); }); }); 

但是,如果我做了多个电话,像这样:

 var mydb = require('./mydb'); mydb.query(function(collection) { collection.find({}, { limit: 10 }).toArray(function(err, docs) { console.log(docs); }); }); mydb.query(function(collection) { collection.find({}, { limit: 10 }).toArray(function(err, docs) { console.log(docs); }); }); 

我得到一个例外:

 Error: db object already connecting, open cannot be called multiple times 

我觉得有一些基本的东西我不明白,这个问题很可能是愚蠢的。

无论如何,所有的帮助是受欢迎的。

提前致谢。

mydb.js

 var mongodb= require('mongodb'), server = new mongodb.Server('staff.mongohq.com', 10030, { auto_reconnect: true }), db1 = new mongodb.Db('mydb', server); // callback: (err, db) function openDatabase(callback) { db1.open(function(err, db) { if (err) return callback(err); console.log('Database connected'); return callback(null, db); }); } // callback: (err, collection) function authenticate(db, username, password, callback) { db.authenticate(username, password, function(err, result) { if (err) { return callback (err); } if (result) { var collection = new mongodb.Collection(db, 'test'); // always, ALWAYS return the error object as the first argument of a callback return callback(null, collection); } else { return callback (new Error('authentication failed')); } }); } exports.openDatabase = openDatabase; exports.authenticate = authenticate; 

use.js

 var mydb = require('./mydb'); // open the database once mydb.openDatabase(function(err, db) { if (err) { console.log('ERROR CONNECTING TO DATABASE'); console.log(err); process.exit(1); } // authenticate once after you opened the database. What's the point of // authenticating on-demand (for each query)? mydb.authenticate(db, 'usernsame', 'password', function(err, collection) { if (err) { console.log('ERROR AUTHENTICATING'); console.log(err); process.exit(1); } // use the returned collection as many times as you like INSIDE THE CALLBACK collection.find({}, {limit: 10}) .toArray(function(err, docs) { console.log('\n------ 1 ------'); console.log(docs); }); collection.find({}, {limit: 10}) .toArray(function(err, docs) { console.log('\n------ 2 ------'); console.log(docs); }); }); }); 

结果:

成功:

  Database connected Database user authenticated ------ 1 ------ [ { _id: 4f86889079a120bf04e48550, asd: 'asd' } ] ------ 2 ------ [ { _id: 4f86889079a120bf04e48550, asd: 'asd' } ] 

失败时:

 Database connected { [MongoError: auth fails] name: 'MongoError', errmsg: 'auth fails', ok: 0 } 

[原始回答]:

你打开db多次(每个query一次)。 您应该只打开一次数据库,并在callback中使用db对象以备后用。

您多次使用相同的variables名称,这可能会造成一些混淆。

 var mongodb = require('mongodb'), server = new mongodb.Server('staff.mongohq.com', 10030, { auto_reconnect: true }), db1 = new mongodb.Db('mydb', server); function authenticateAndGo(db, handle) { db.authenticate('username', 'password', function(err) { if (err) { console.log(err); return; } console.log('Database user authenticated'); var collection = new mongodb.Collection(db, 'test'); handle(collection); }); } function query(handle) { db1.open(function(err, db2) { if( err ) { console.log(err); return; } console.log('Database connected'); authenticateAndGo(db2, handle); }); }; exports.query = query; 

我已经改变了上面的代码( db1为原始数据库, db2打开的数据库)。 正如你所看到的,你打开db1多次,这是不好的。 提取代码打开到另一个方法,并使用它一次,并使用db2实例所有查询/更新/删除/ …

您只能调用一次“打开”。 当打开的callback触发时,您可以对其返回的数据库对象进行查询。 所以处理这个问题的一种方法是排队请求,直到打开完成。 例如MyMongo.js

 var mongodb = require('mongodb'); function MyMongo(host, port, dbname) { this.host = host; this.port = port; this.dbname = dbname; this.server = new mongodb.Server( 'localhost', 9000, {auto_reconnect: true}); this.db_connector = new mongodb.Db(this.dbname, this.server); var self = this; this.db = undefined; this.queue = []; this.db_connector.open(function(err, db) { if( err ) { console.log(err); return; } self.db = db; for (var i = 0; i < self.queue.length; i++) { var collection = new mongodb.Collection( self.db, self.queue[i].cn); self.queue[i].cb(collection); } self.queue = []; }); } exports.MyMongo = MyMongo; MyMongo.prototype.query = function(collectionName, callback) { if (this.db != undefined) { var collection = new mongodb.Collection(this.db, collectionName); callback(collection); return; } this.queue.push({ "cn" : collectionName, "cb" : callback}); } 

然后用样本:

 var MyMongo = require('./MyMongo.js').MyMongo; var db = new MyMongo('localhost', 9000, 'db1'); var COL = 'col'; db.query(COL, function(collection) { collection.find({}, { limit: 10 }).toArray(function(err, docs) { console.log("First:\n", docs); }); }); db.query(COL, function(collection) { collection.find({}, { limit: 10 }).toArray(function(err, docs) { console.log("\nSecond:\n", docs); }); }); 

我直接在db init之后直接调用open函数:

 var mongodb = require('mongodb'); var server = new mongodb.Server('foo', 3000, {auto_reconnect: true}); var db = new mongodb.Db('mydb', server); db.open(function(){}); 

之后,我不必再关心,因为auto_reconnect是真的。

 db.collection('bar', function(err, collection) { [...] };