【问题标题】:how to connect to mongodb synchronously in nodejsnodejs中如何同步连接mongodb
【发布时间】:2016-09-05 22:10:50
【问题描述】:

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

这是我想出的东西

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() {

    }
}

我想在我的初始代码中的某处设置一个连接,如下面的那个,然后将连接重用于不同的类,就像猫鼬或僧侣所做的那样,但只使用 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);
   });

现在,db 在主要的 MongoDB 类中返回 undefined,并且无法通过 google 或文档对其进行调试。

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

【问题讨论】:

    标签: node.js mongodb node-mongodb-native


    【解决方案1】:

    我一直在努力解决这个问题,特别是在跨调用的 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);
          }
        });
      });
    }

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

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

    【讨论】:

      【解决方案2】:

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

      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】:

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

        module.exports = {
        
            connect: function(dbName,  callback ) {
               MongoClient.connect(dbName, function(err, db) {
        
               _db = db;
               return callback( err );
            });
        },
        
             getDb: function() {
                return _db;
             }
        };
        

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

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

        考虑到您在 js 文件中创建了模块,您可以简单地使用 require 来获取数据库连接

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

        并获得连接使用

        var db = MongoConnection.getDb();
        

        【讨论】:

        • 谢谢,我的问题有问题。我假设一个承诺是同步的,因此我的代码中有一些错误,但感谢这条信息,因为它对我非常有用。
        猜你喜欢
        • 2014-11-12
        • 2014-03-28
        • 1970-01-01
        • 1970-01-01
        • 2022-01-07
        • 2016-12-05
        • 1970-01-01
        • 2023-02-07
        • 2019-10-01
        相关资源
        最近更新 更多