如何在node.js中重复使用mongodb连接

6

我正在使用node-mongodb-native驱动程序和mongodb编写网站。

我有一个关于如何打开mongodb连接一次,然后在user.js中的用户集合和comment.js中的帖子集合中使用它的问题。

我想在db.js中打开db连接,然后将数据插入/保存到用户和帖子集合中。

目前的代码,我的db.js

var Db = require('mongodb').Db,
    Connection = require('mongodb').Connection,
    Server = require('mongodb').Server;
module.exports = new Db(
    'blog', 
    new Server('localhost', Connection.DEFAULT_PORT, {auto_reconnect: true})
);

我在user.js中使用了db.js,如下所示。
var mongodb = require('./db');

function User(user){
  this.name = user.name;
  this.password = user.password;
  this.email = user.email;
};

module.exports = User;

User.prototype.save = function(callback) {//save user information
  //document to save in db
  var user = {
      name: this.name,
      password: this.password,
      email: this.email
  };
  mongodb.close();
  //open mongodb database
  mongodb.open(function(err, db){
    if(err){
      return callback(err);
    }
    //read users collection
    db.collection('users', function(err, collection){
      if(err){
        mongodb.close();
        return callback(err);
      }
      //insert data into users collections
      collection.insert(user,{safe: true}, function(err, user){
        mongodb.close();
        callback(err, user);//success return inserted user information
      });
    });
  });
};

以及comment.js

var mongodb = require('./db');

function Comment(name, day, title, comment) {
  this.name = name;
  this.day = day;
  this.title = title;
  this.comment = comment;
}

module.exports = Comment;

Comment.prototype.save = function(callback) {
  var name = this.name,
      day = this.day,
      title = this.title,
      comment = this.comment;
  mongodb.open(function (err, db) {
    if (err) {
      return callback(err);
    }
    db.collection('posts', function (err, collection) {
      if (err) {
        mongodb.close();
        return callback(err);
      }
      //depend on name time and title add comment
      collection.findAndModify({"name":name,"time.day":day,"title":title}
      , [ ['time',-1] ]
      , {$push:{"comments":comment}}
      , {new: true}
      , function (err,comment) {
          mongodb.close();
          callback(null);
      });   
    });
  });
};

你的问题听起来不像是一个问题。具体是什么没有发生?请发布你所面临的确切挑战。 - moka
2个回答

8
您只需连接一次,然后可以重复使用多次:
var mongodb = require('mongodb');
var events = require('events');
var event = new events.EventEmitter();
var access = new mongodb.Server(host, port, { });
var client = null;

new mongodb.Db('YOUR DATABASE', access, { safe: true, auto_reconnect: true }).open(function (err, c) {
  if (!err) {
    client = c;
    console.log('database connected');
    event.emit('connect');
  } else {
    console.log('database connection error', err);
    event.emit('error');
  }
});

exports.get = function(fn) {
  if(client) {
    fn(client);
  } else {
    event.on('connect', function() {
      fn(client);
    });
  }
};

然后重新使用它:

var db = require('./db');
var items;
db.get(function(client) {
  items = new mongodb.Collection(client, 'collection');
});

// then anywhere in your code
db.get(function() {
  // items.find({ ...
});

你尝试理解并应用上面答案中的思路和代码了吗?如果没有,请尝试一下。如果是的话,请分享在你的情况下具体失败了什么。 - moka
因为在执行任何逻辑之前,您需要首先实际连接到数据库。 - moka
连接是异步发生的,因此如果您调用.open - 它不会立即可用。 - moka
我已经改进了上面的代码,请您审核并告知尝试的结果。使用了异步单例模式。 - moka
你复制代码错误了。var ee = require('events').EventEmitter();是错误的,因为它没有创建 EventEmitter。请参考上面的答案或将该行更改为:var ee = new (require('events').EventEmitter); - moka
显示剩余4条评论

2

接受的答案已经三年过去了,无法与最新的node-mongodb-native驱动程序一起使用。我修改了@moka的答案,并添加了一些延迟和重试逻辑。

var MongoClient = require('mongodb').MongoClient;
var events = require('events');
var event = new events.EventEmitter();
var database = null;
var retries = 0;
var delay = 300;

setTimeout(connect,delay);

// Use connect method to connect to the server
function connect(){
    MongoClient.connect(process.env.MONGODB_URL, function(err, db) {
        if(!err){
            console.log("Connected successfully to server");
            database = db;
            event.emit('dbconnect');

        } else {
            if(retries < 4){
                console.log('Retrying to connect db %s', retries++);
                setTimeout(connect,delay);
            } else {
                console.log('Unable to connect db');
            }
        }
    });
}


exports.get = function(fn) {
    if(database !== null) {
        fn(database);
    } else {
        event.on('dbconnect', function() {
            fn(database);
        });
    }
};

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接