如何在nodejs中同步连接到mongodb

时间:2021-06-21 03:00:57

I want to make use of the promises feature where in I can connect to mongodb synchronously and I can reuse the connection by passing it on to different modules.

我想利用promises功能,我可以同步连接到mongodb,我可以通过将连接传递给不同的模块来重用连接。

Here is something that I came up with

这是我想出来的东西

class MongoDB {

    constructor(db,collection) {      
      this.collection = db.collection(collection);
    }

    find(query, projection) {
        if(projection)
            return this.collection.find(query, projection);
        else
            return this.collection.find(query);
    }
}

class Crew extends MongoDB {

    constructor(db) {        
        super(db,'crews');
    }

    validate() {

    }
}

I want to setup a connection somewhere in my initial code like the one below and then reuse the connection for different classes, just like how mongoose or monk does but using only the node-mongodb-native package.

我想在我的初始代码中的某个位置设置一个连接,如下面的那个,然后重用不同类的连接,就像mongoose或monk一样,但只使用node-mongodb-native包。

MongoClient.connect(url)
          .then( (err,dbase) => {
                global.DB = dbase;
              });


var Crew = new CrewModel(global.DB);


Crew.find({})
   .then(function(resp) {
      console.log(resp);
   });

Right now, the db returns undefined inside the main MongoDB class and am not able to debug this one out through google or the documentation.

现在,db在主MongoDB类中返回undefined,并且无法通过谷歌或文档调试这个。

Edit: I had assumed that a promise was synchronous but that is not the case.

编辑:我曾假设承诺是同步的,但事实并非如此。

3 个解决方案

#1


7  

To reuse the connection I would create a module like this.

要重用连接,我会创建一个这样的模块。

module.exports = {

    connect: function(dbName,  callback ) {
       MongoClient.connect(dbName, function(err, db) {

       _db = db;
       return callback( err );
    });
},

     getDb: function() {
        return _db;
     }
};

After that you can connect to the database before starting your application

之后,您可以在启动应用程序之前连接到数据库

MongoConnection.connect("mongodb://localhost:27017/myDatabase", function(err){
    app.listen(3000, function () {
        // you code
    });
});

Considering you created the module in a js file you can simply use require to get the databaseConnection

考虑到您在js文件中创建了模块,您只需使用require来获取databaseConnection

var dbConnection = require("./myMongoConnection.js");

and to get the connection use

并获得连接使用

var db = MongoConnection.getDb();

#2


0  

Another option using ES6 classes creates a singleton object that you can access repeatedly. It's inspired by @user3134009's answer here.

使用ES6类的另一个选项是创建一个可以重复访问的单例对象。它的灵感来自@ user3134009的答案。

const EventEmitter = require('events');
const MongoClient = require('mongodb').MongoClient;
const config = require('config');

let _db = null;

class MongoDBConnection extends EventEmitter {
  constructor() {
    super();
    this.emit("dbinit", this);
    if (_db == null) {
      console.log("Connecting to MongoDB...");
      MongoClient.connect(config.dbs.mongo.url, config.dbs.mongo.options, 
(err, db) => {
        if (err) {
           console.error("MongoDB Connection Error", err);
          _db = null;
        } else {
          console.log("Connected to MongoDB", config.dbs.mongo.url);
          db.on('close', () => { console.log("MongoDB closed", arguments); _db = null; });
          db.on('reconnect', () => { console.log("MongoDB reconnected", arguments); _db = db; });
          db.on('timeout', () => { console.log("MongoDB timeout", arguments); });
          _db = db;
          this.emit('dbconnect', _db);
        }
      });
    }
  }
  getDB() {
    return _db;
  }
}
module.exports = new MongoDBConnection();

#3


0  

I have been struggling with this problem for a while, and in particular with setting up and persisting MongoDb connection in AWS lambda functions across invocations. Thanks to @toszter answer I've finally come up with the following solution:

我一直在努力解决这个问题,特别是在调用AWS lambda函数中设置和持久化MongoDb连接。感谢@toszter回答我终于想出了以下解决方案:

const mongodb = require('mongodb');
const config  = require('./config.json')[env];
const client  = mongodb.MongoClient;

const mongodbUri = `mongodb://${config.mongo.user}:${config.mongo.password}@${config.mongo.url}/${config.mongo.database}`;


const options = {
  poolSize: 100, 
  connectTimeoutMS: 120000, 
  socketTimeoutMS: 1440000
 };

// connection object
let _db = null;

class MongoDBConnection {
  constructor() {}

  // return a promise to the existing connection or the connection function
  getDB() {
    return (_db ? Promise.resolve(_db) : mConnect());
  }
}

module.exports = new MongoDBConnection();

// transforms into a promise Mongo's client.connect
function mConnect() {
  return new Promise((resolve, reject) => {
    console.log('Connecting to Mongo...');
    client.connect(mongodbUri, options, (error, db) => {
      if (error)  {
        _db = null;
        return reject(error);
      }
      else {
        console.log('Connected to Mongo...');
        _db = db;
        resolve(db);
      }
    });
  });
}

To use it in a controller or app.js:

要在控制器或app.js中使用它:

  const mongoConfig  =  require('mongoConfig');
  mongoConfig.getDB()
    .then(db => db.collection('collection').find({}))
    .catch(error => {...});

#1


7  

To reuse the connection I would create a module like this.

要重用连接,我会创建一个这样的模块。

module.exports = {

    connect: function(dbName,  callback ) {
       MongoClient.connect(dbName, function(err, db) {

       _db = db;
       return callback( err );
    });
},

     getDb: function() {
        return _db;
     }
};

After that you can connect to the database before starting your application

之后,您可以在启动应用程序之前连接到数据库

MongoConnection.connect("mongodb://localhost:27017/myDatabase", function(err){
    app.listen(3000, function () {
        // you code
    });
});

Considering you created the module in a js file you can simply use require to get the databaseConnection

考虑到您在js文件中创建了模块,您只需使用require来获取databaseConnection

var dbConnection = require("./myMongoConnection.js");

and to get the connection use

并获得连接使用

var db = MongoConnection.getDb();

#2


0  

Another option using ES6 classes creates a singleton object that you can access repeatedly. It's inspired by @user3134009's answer here.

使用ES6类的另一个选项是创建一个可以重复访问的单例对象。它的灵感来自@ user3134009的答案。

const EventEmitter = require('events');
const MongoClient = require('mongodb').MongoClient;
const config = require('config');

let _db = null;

class MongoDBConnection extends EventEmitter {
  constructor() {
    super();
    this.emit("dbinit", this);
    if (_db == null) {
      console.log("Connecting to MongoDB...");
      MongoClient.connect(config.dbs.mongo.url, config.dbs.mongo.options, 
(err, db) => {
        if (err) {
           console.error("MongoDB Connection Error", err);
          _db = null;
        } else {
          console.log("Connected to MongoDB", config.dbs.mongo.url);
          db.on('close', () => { console.log("MongoDB closed", arguments); _db = null; });
          db.on('reconnect', () => { console.log("MongoDB reconnected", arguments); _db = db; });
          db.on('timeout', () => { console.log("MongoDB timeout", arguments); });
          _db = db;
          this.emit('dbconnect', _db);
        }
      });
    }
  }
  getDB() {
    return _db;
  }
}
module.exports = new MongoDBConnection();

#3


0  

I have been struggling with this problem for a while, and in particular with setting up and persisting MongoDb connection in AWS lambda functions across invocations. Thanks to @toszter answer I've finally come up with the following solution:

我一直在努力解决这个问题,特别是在调用AWS lambda函数中设置和持久化MongoDb连接。感谢@toszter回答我终于想出了以下解决方案:

const mongodb = require('mongodb');
const config  = require('./config.json')[env];
const client  = mongodb.MongoClient;

const mongodbUri = `mongodb://${config.mongo.user}:${config.mongo.password}@${config.mongo.url}/${config.mongo.database}`;


const options = {
  poolSize: 100, 
  connectTimeoutMS: 120000, 
  socketTimeoutMS: 1440000
 };

// connection object
let _db = null;

class MongoDBConnection {
  constructor() {}

  // return a promise to the existing connection or the connection function
  getDB() {
    return (_db ? Promise.resolve(_db) : mConnect());
  }
}

module.exports = new MongoDBConnection();

// transforms into a promise Mongo's client.connect
function mConnect() {
  return new Promise((resolve, reject) => {
    console.log('Connecting to Mongo...');
    client.connect(mongodbUri, options, (error, db) => {
      if (error)  {
        _db = null;
        return reject(error);
      }
      else {
        console.log('Connected to Mongo...');
        _db = db;
        resolve(db);
      }
    });
  });
}

To use it in a controller or app.js:

要在控制器或app.js中使用它:

  const mongoConfig  =  require('mongoConfig');
  mongoConfig.getDB()
    .then(db => db.collection('collection').find({}))
    .catch(error => {...});