Best way to connect to MongoDB using Node.js [dupl

2019-01-24 16:16发布

问题:

This question already has an answer here:

  • How do I manage MongoDB connections in a Node.js web application? 10 answers

I've read a few guides on how to use Mongo with Node, and they all seem to connect to databases differently. One particular way that worked well for me was:

MongoClient.connect("mongodb://localhost:27017/exampleDb", function(err, db) {
  if(err) { return console.dir(err); }

  db.createCollection('users', function(err, collection) {});

  //Do all server/database operations in here

});

However, this seems inefficient/odd to me, I would have to reconnect to the database every time there is an app.get(), like for making a new user or retrieving information.

Another way that seems better suited to me is

var mongoose = require("mongoose")
var db = mongoose.connect("localhost:27107/users");

db.createCollection('users', function(err, collection) {});

I've seen several sites do something along these lines, but I personally can't get the above to work. I keep getting the error TypeError: db.createCollection is not a function server-side. So, my question is why the above code doesn't work, if the first code is a good alternative, and if there are any other ways to do this.

回答1:

You can use a global variable to hold the connection (e.g. db), for example:

var db = null // global variable to hold the connection

MongoClient.connect('mongodb://localhost:27017/', function(err, client) {
    if(err) { console.error(err) }
    db = client.db('test') // once connected, assign the connection to the global variable
})

app.get('/', function(req, res) {
    db.collection('test').find({}).toArray(function(err, docs) {
        if(err) { console.error(err) }
        res.send(JSON.stringify(docs))
    })
})

Or, if you prefer, you can also use the Promise object that is returned by MongoClient if it is called without a callback argument:

var conn = MongoClient.connect('mongodb://localhost:27017/') // returns a Promise

app.get('/', function(req, res) {
    conn.then(client=> client.db('test').collection('test').find({}).toArray(function(err, docs) {
        if(err) { console.error(err) }
        res.send(JSON.stringify(docs))
    }))
})

Please note that I used the ES6 fat arrow function definition in the second example.

You are absolutely correct that you should not call MongoClient every time. Using a global variable or Promises allows the MongoDB node.js driver to create a connection pool, which achieves at least two good things:

  • Connections are reused in a pool, so there is no multiple expensive setup/teardown process for the lifetime of your application. You connect once, and let the driver take care of the rest for you.
  • You can control the amount of connection your application makes into the database, by limiting the size of the connection pool.

Edit 2018-08-24: The MongoClient.connect() method in node.js driver version 3.0 and newer returns a client object instead of a database object. The examples above were modified to keep it up to date with the latest node.js driver version.



回答2:

You could use it this way:

that's server.js file:

import path from 'path'
import express from 'express'
import bodyParser from 'body-parser'
import morgan from 'morgan'
import db from './server/database'
import routes from './server/routes'

import webpack from 'webpack'
import webpackDevMiddleware from 'webpack-dev-middleware'
import webpackHotMiddleware from 'webpack-hot-middleware'
import webpackConfig from './config/webpack'
const app = express()
const port = process.env.PORT || process.env.NODE_PORT
const compiler = webpack(webpackConfig)

db(λ => {
  app.use(webpackDevMiddleware(compiler, { noInfo: true, publicPath: webpackConfig.output.publicPath }))
  app.use(webpackHotMiddleware(compiler))
  app.use(morgan('dev'))
  app.use(bodyParser.json({ limit: '20mb' }))
  app.use(bodyParser.urlencoded({ limit: '20mb', extended: false }))
  app.use('/static', express.static('static'));
  //app.use('/api', jwt)
  app.use('/api', routes())

  app.set('json spaces', 2)

  app.get('*', function(request, response) {
    response.sendFile(path.resolve(__dirname, 'index.html'))
  })

  app.listen(port, (error) => {
    if (error) {
      console.error(error)
      throw error
    } else {
      console.info(`==>