使用 Node.js 连接到 MongoDB 的最佳方式 [重复]
Posted
技术标签:
【中文标题】使用 Node.js 连接到 MongoDB 的最佳方式 [重复]【英文标题】:Best way to connect to MongoDB using Node.js [duplicate] 【发布时间】:2016-11-23 22:40:40 【问题描述】:我已经阅读了一些关于如何将 Mongo 与 Node 一起使用的指南,它们似乎都以不同的方式连接到数据库。一种特别适合我的方法是:
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
);
但是,这对我来说似乎效率低下/奇怪,每次有 app.get()
时,我都必须重新连接到数据库,例如创建新用户或检索信息。
另一种似乎更适合我的方式是
var mongoose = require("mongoose")
var db = mongoose.connect("localhost:27107/users");
db.createCollection('users', function(err, collection) );
我已经看到几个网站在这些方面做了一些事情,但我个人无法让上述内容起作用。我不断收到错误TypeError: db.createCollection is not a function
服务器端。所以,我的问题是为什么上面的代码不起作用,如果第一个代码是一个很好的选择,以及是否有其他方法可以做到这一点。
【问题讨论】:
【参考方案1】:您可以使用全局变量来保持连接(例如db
),例如:
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))
)
)
或者,如果您愿意,也可以使用 MongoClient
返回的 Promise 对象,如果它在没有回调参数的情况下调用:
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))
))
)
请注意,我在第二个示例中使用了ES6 fat arrow function definition。
您绝对正确,您不应该每次都致电MongoClient
。使用全局变量或 Promises 可以让 MongoDB node.js 驱动创建一个连接池,这至少实现了两个好处:
编辑 2018-08-24:node.js 驱动程序 3.0 及更高版本中的 MongoClient.connect()
方法返回 client object 而不是数据库对象。修改了上面的示例以使其与最新的 node.js 驱动程序版本保持同步。
【讨论】:
我得到通用处理程序 TypeError: db.collection is not a function error.When I used the first example of ur's.我该如何解决这个问题? 请查看更新后的答案。 您能否展示如何正确创建池以供重复使用,以及如果其中一个发生错误时如何更新它们?【参考方案2】:我写了一篇关于如何在 express 中重用 mongodb 连接的教程。你可以看到here。基本上,它是一个简单的模块,你可以像这样与 expressjs 一起使用:
var connection = require('./dbconnection');
// url and optional config.
app.use(connection(app, 'mongourl', );
这是连接的代码:
module.exports = function(app, uri, opts)
if (typeof uri !== 'string')
throw new TypeError('Error: Unexpected mongodb connection url');
opts = opts || ;
var property = opts.property || 'db';
var connection;
return function expressMongoDb(req, res, next)
if (!connection)
connection = MongoClient.connect(uri, opts);
connection
.then(function (db)
req[property] = db;
app.set('mongodb', db);
next();
)
.catch(function (err)
connection = undefined;
next(err);
);
;
;
【讨论】:
【参考方案3】:你可以这样使用它:
那是 server.js 文件:
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(`==> ? Listening on port $port. Open up http://localhost:$port/ in your browser.`)
)
)
服务器/数据库.js
import mongoose from 'mongoose'
export default callback =>
const MONGO_URL, MONGO_PORT, MONGO_DB = process.env
mongoose.connect(`mongodb://$MONGO_URL:$MONGO_PORT/$MONGO_DB`, error =>
if (error)
console.error('Please make sure your MongoDB configuration is correct and that service is running')
throw error
)
callback()
然后你必须定义你的猫鼬模型,例如:
import mongoose, Schema from 'mongoose'
const ideaSchema = new Schema(
title:
type: String,
required: true
,
slug:
type: String,
required: true,
unique: true
,
description:
type: String,
required: true
)
export default mongoose.model('Idea', ideaSchema)
只需以这种方式使用控制器:
import HttpStatus from 'http-status-codes'
import mongoose from 'mongoose'
import sanitize from 'sanitize-html'
import slug from 'slug'
import Idea from '../models/idea'
const findAllIdeas = (req, res) =>
Idea.find()
.select('user title slug createdAt updatedAt')
.populate(
path: 'user',
select: 'firstName lastName'
)
.then(data => res.status(HttpStatus.OK).json(data))
.catch(error => res.status(HttpStatus.BAD_REQUEST).json(error))
export default findAllIdeas, findIdeaBySlug, createIdea, addComment
您不必为每个 get 请求连接到 mongoDB。
所以你的路线看起来像这样。很简单:
import Router from 'express'
import controller from '../controllers/idea'
const router = Router()
router.route('/')
.get(controller.findAllIdeas)
.post(controller.createIdea)
router.route('/:slug')
.get(controller.findIdeaBySlug)
router.route('/comment')
.post(controller.addComment)
export default router
【讨论】:
非常有趣,感谢您的帮助。我个人对使用任何我不理解的代码(在这个程度上)犹豫不决,尽管我会解决这个问题, 我认为这比 OP 要求的要多...【参考方案4】:我的首选代码如下:
mongoose.connect(YOUR_URL ,function(err)
if (err)
console.log(err);
else
console.log("Connected to DB");
);
还可以尝试仅连接到 localhost:27107
,这可能是您的问题。
【讨论】:
是的,这行得通,但正如我所问的,它是否足够高效地用于每个app.get()
?或者那是无关紧要的?
是的,只要把这段代码放在server.js
中,在其他要查询MongoDB的文件中,只需var mongoose = require('mongoose');
,然后var Model= require('./models/MODEL');
,如果在server.js中,它只会启动时连接一次。以上是关于使用 Node.js 连接到 MongoDB 的最佳方式 [重复]的主要内容,如果未能解决你的问题,请参考以下文章
Docker - Node.js + MongoDB - “错误:无法连接到 [localhost:27017]”
将 Nowjs 托管的 Node.js 服务器连接到 MongoDB Atlas DB
Kubernetes node.js 容器无法连接到 MongoDB Atlas