什么是在NodeJs中处理Mongodb全局连接的最佳方法

时间:2018-03-21 03:23:07

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

我使用Node-Mongo-Native并尝试设置全局连接变量,但我对两种可能的解决方案感到困惑。你能帮我解决哪一个会是好人吗? 1.解决方案(这很糟糕,因为每个请求都会尝试创建新连接。)

var express = require('express');  
var app = express();  
var MongoClient = require('mongodb').MongoClient;  
var assert = require('assert');

// Connection URL
var url = '[connectionString]]';

// start server on port 3000
app.listen(3000, '0.0.0.0', function() {  
  // print a message when the server starts listening
  console.log("server starting");
});

// Use connect method to connect to the server when the page is requested
app.get('/', function(request, response) {  
  MongoClient.connect(url, function(err, db) {
    assert.equal(null, err);
    db.listCollections({}).toArray(function(err, collections) {
        assert.equal(null, err);
        collections.forEach(function(collection) {
            console.log(collection);
        });
        db.close();
    })
    response.send('Connected - see console for a list of available collections');
  });
});
  1. 解决方案(在app init处连接并将连接字符串分配给全局变量)。但我相信将连接字符串分配给全局变量并不是一个好主意。

    var mongodb; var url =' [connectionString]&#39 ;; MongoClient.connect(url,function(err,db){
        assert.equal(null,err);     mongodb的=分贝;     } );

  2. 我想在应用初始化时创建连接,并在整个应用生命周期内使用。

    你能帮助我吗?感谢。

5 个答案:

答案 0 :(得分:12)

创建一个Connection类来管理apps数据库连接。

const MongoClient = require('mongodb').MongoClient

class Connection {
    static connectToMongo() {
        if ( this.db ) return Promise.resolve(this.db)
        return MongoClient.connect(this.url, this.options)
            .then(db => this.db = db)
    }
}

Connection.db = null
Connection.url = 'mongodb://127.0.0.1:27017/test_db'
Connection.options = {
    bufferMaxEntries:   0,
    reconnectTries:     5000,
    useNewUrlParser: true
}

module.exports = { Connection }

require('./Connection.js')的任何地方都可以使用Connection.connectToMongo()方法,Connection.db属性也是如此。

const router = require('express').Router()
const { Connection } = require('../lib/Connection.js')

router.get('/files', (req, res) => {
   Connection.db.collection('files').find({})
     .then(files => res.json({ files: files })
     .catch(err => res.json({ error: err })
})

module.exports = router

答案 1 :(得分:1)

另一种更直接的方法是利用Express的内置功能在应用程序中的路由和模块之间共享数据。有一个名为app.locals的对象。我们可以将属性附加到它并从我们的路线内部访问它。要使用它,请在app.js文件中实例化mongo连接。

var app = express();

MongoClient.connect('mongodb://localhost:27017/')
.then(client =>{
  const db = client.db('your-db');
  const collection = db.collection('your-collection');
  app.locals.collection = collection;
});
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              // view engine setup
app.set('views', path.join(__dirname, 'views'));

现在可以使用req.app.locals在下面的路由中访问此数据库连接或实际上希望共享给您的模块的任何其他数据,而无需创建和需要其他模块。

app.get('/', (req, res) => {
  const collection = req.app.locals.collection;
  collection.find({}).toArray()
  .then(response => res.status(200).json(response))
  .catch(error => console.error(error));
});

此方法可确保您在应用程序运行期间一直打开数据库连接,除非您选择随时关闭它。 req.app.locals.your-collection可以轻松访问它,并且不需要创建任何其他模块。

答案 2 :(得分:0)

模块版本^ 3.1.8

将连接初始化为承诺:

const MongoClient = require('mongodb').MongoClient
const uri = 'mongodb://...'
const client = new MongoClient(uri)
const connection = client.connect()

然后在您希望对数据库执行任何操作时调用连接:

app.post('/insert', (req, res) => {
    const connect = connection
    connect.then(() => {
        const doc = { id: 3 }
        const db = client.db('database_name')
        const coll = db.collection('collection_name')
        coll.insertOne(doc, (err, result) => {
            if(err) throw err
        })
    })
})  

答案 3 :(得分:0)

这就是我的做法。

            // custom class
            const MongoClient = require('mongodb').MongoClient
            const credentials = "mongodb://user:pass@mongo"

            class MDBConnect {
                static connect (db, collection) {
                    return MongoClient.connect(credentials)
                        .then( client => {
                            return client.db(db).collection(collection);
                        })
                        .catch( err => { console.log(err)});
                }
                static findOne(db, collection, query) {
                    return MDBConnect.connect(db,collection)
                        .then(c => {
                            return c.findOne(query)
                                        .then(result => {
                                            return result;
                                        });
                        })
                }
                // create as many as you want
                //static find(db, collection, query)
                //static insert(db, collection, query)
                // etc etc etc
            }
            module.exports = MDBConnect;


            // in the route file
            var express = require('express');
            var router = express.Router();
            var ObjectId = require('mongodb').ObjectId; 
            var MDBConnect =  require('../storage/MDBConnect');

            // Usages
            router.get('/q/:id', function(req, res, next) {
                let sceneId = req.params.id;

                // user case 1
                MDBConnect.connect('gameapp','scene')
                    .then(c => {
                        c.findOne({_id: ObjectId(sceneId)})
                            .then(result => {
                                console.log("result: ",result);
                                res.json(result);
                            })
                    });
                // user case 2, with query
                MDBConnect.findOne('gameapp','scene',{_id: ObjectId(sceneId)})
                    .then(result => {
                        res.json(result);
                    });
            });

答案 4 :(得分:0)

在Express中,您可以像这样添加mongo连接

Runnable

,以后您可以以req.db

的形式访问它
import {MongoClient} from 'mongodb';
import express from 'express';
import bodyParser from 'body-parser';
    let mongoClient = null;
    MongoClient.connect(config.mongoURL, {useNewUrlParser: true, useUnifiedTopology: true},function (err, client) {
        if(err) {
          console.log('Mongo connection error');
        } else {
          console.log('Connected to mongo DB');
          mongoClient = client;
        }
    })
let app = express();
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());

app.use((req,res,next)=>{
    req.db = mongoClient.db('customer_support');
    next();
});
相关问题