如何在nodejs中同步连接到mongodb
how to connect to mongodb synchronously in nodejs
我想利用 promises 功能,在其中我可以同步连接到 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() {
}
}
我想在我的初始代码中的某处设置一个连接,如下所示,然后为不同的 classes 重用该连接,就像 mongoose 或 monk 所做的一样,但只使用 node-mongodb-原生包。
MongoClient.connect(url)
.then( (err,dbase) => {
global.DB = dbase;
});
var Crew = new CrewModel(global.DB);
Crew.find({})
.then(function(resp) {
console.log(resp);
});
现在,数据库 returns 在主 MongoDB class 中未定义,我无法通过 google 或文档调试它。
编辑:我曾假设 promise 是同步的,但事实并非如此。
为了重用连接,我会创建一个这样的模块。
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();
另一个使用 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();
我已经为这个问题苦苦挣扎了一段时间,特别是在跨调用的 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 => {...});
我想利用 promises 功能,在其中我可以同步连接到 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() {
}
}
我想在我的初始代码中的某处设置一个连接,如下所示,然后为不同的 classes 重用该连接,就像 mongoose 或 monk 所做的一样,但只使用 node-mongodb-原生包。
MongoClient.connect(url)
.then( (err,dbase) => {
global.DB = dbase;
});
var Crew = new CrewModel(global.DB);
Crew.find({})
.then(function(resp) {
console.log(resp);
});
现在,数据库 returns 在主 MongoDB class 中未定义,我无法通过 google 或文档调试它。
编辑:我曾假设 promise 是同步的,但事实并非如此。
为了重用连接,我会创建一个这样的模块。
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();
另一个使用 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();
我已经为这个问题苦苦挣扎了一段时间,特别是在跨调用的 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 => {...});