我在express中使用mongodb本机驱动程序。js应用程序。数据库中大约有6个集合,因此我创建了6个js文件,每个文件都有一个集合作为javascript对象(例如function collection(){}
),原型函数处理这些集合上的所有操作。我觉得这是一个很好的建筑。
但我遇到的问题是如何连接到数据库?我应该在每个文件中创建一个连接并使用它们吗?我认为这太过分了,因为mongodb本机驱动程序中的connect会创建一个连接池,而拥有几个连接是不合理的。
那么如何创建一个连接池并在所有collections.js文件中使用它呢?我想在猫鼬中实现这样的连接。让我知道我在应用程序架构中的任何思考过程是否错误。
使用Mongoose可以解决这些问题,但我在几个地方读到它比本地驱动程序慢,而且我更喜欢无模式模型。
编辑:我用模型创建了一个模块。每个集合都位于一个文件中,它将数据库作为参数。现在在索引中。js文件我调用了数据库连接,并在从连接中获取数据库后保留了一个变量db。(我使用了自动重新连接功能来确保连接没有丢失)。在同一个索引中。js文件我像这样导出了每个集合
exports.model1 = require('./model1').(db)
exprorts.model2 = require('./model2').(db)
这确保了数据库部分只在一个模块中处理,应用程序只需调用每个模型所需的函数。导出的js文件,如save()
,fincdbyid()
等(在函数中执行的任何操作都由您来实现)。
我只是想我会添加我自己的MongoDB连接方法,供其他有兴趣或有问题的人使用不同的方法
此方法假定您不需要身份验证(我在本地主机上使用此方法)
认证还是很容易实现的
var MongoClient = require('mongodb').MongoClient;
var Server = require('mongodb').Server;
var client = new MongoClient(new Server('localhost',27017,{
socketOptions: {connectTimeoutMS: 500},
poolSize:5,
auto_reconnect:true
}, {
numberOfRetries:3,
retryMilliseconds: 500
}));
client.open(function(err, client) {
if(err) {
console.log("Connection Failed Via Client Object.");
} else {
var db = client.db("theDbName");
if(db) {
console.log("Connected Via Client Object . . .");
db.logout(function(err,result) {
if(!err) {
console.log("Logged out successfully");
}
client.close();
console.log("Connection closed");
});
}
}
});
布拉德·达格利在他的书(第231-232页)中介绍了这种方法,这是值得称赞的
正如公认的答案所说——您应该只为所有传入请求创建一个连接并重用它,但答案缺少解决方案,它将创建和缓存连接。我编写了Express中间件来实现这一点——Expres-mongo-db。乍一看,这项任务很琐碎,大多数人都使用这种代码:
var db;
function createConnection(req, res, next) {
if (db) { req.db = db; next(); }
client.connect(uri, { auto_reconnect: true }, function (err, database) {
req.db = db = databse;
next();
});
}
app.use(createConnection);
但是,当多个请求同时到达并且db
未定义时,该代码会导致连接泄漏express mongo db
在需要模块时(而不是在第一个请求到达时),通过等待传入的客户端并只调用一次connect
来解决此问题。
希望你觉得有用。
如何连接到数据库?
要使用MongoDB本机驱动程序进行连接,需要执行以下操作:
var util = require('util');
var mongodb = require('mongodb');
var client = mongodb.MongoClient;
var auth = {
user: 'username',
pass: 'password',
host: 'hostname',
port: 1337,
name: 'databaseName'
};
var uri = util.format('mongodb://%s:%s@%s:%d/%s',
auth.user, auth.pass, auth.host, auth.port, auth.name);
/** Connect to the Mongo database at the URI using the client */
client.connect(uri, { auto_reconnect: true }, function (err, database) {
if (err) throw err;
else if (!database) console.log('Unknown error connecting to database');
else {
console.log('Connected to MongoDB database server at:');
console.log('\n\t%s\n', uri);
// Create or access collections, etc here using the database object
}
});
基本连接是这样设置的。这就是我所能给你的,只是你想要的基本描述。发布一些你目前掌握的代码,以获得更具体的帮助。
我应该在每个文件中创建一个连接并使用它们吗?
不
那么如何创建单个连接池并在所有collections.js文件中使用它呢?
您可以使用上面的代码创建一个文件,我们将其称为dbmanager。js
连接到数据库。导出在数据库上运行的createUser
、deleteUser
等功能,然后导出如下功能:
module.exports = {
createUser: function () { ; },
deleteUser: function () { ; }
};
然后,您可以从另一个文件中要求
,如下所示:
var dbman = require('./dbmanager');
dbman.createUser(userData); // using connection established in `dbmanager.js`
编辑:因为我们处理的是JavaScript和单个线程,所以本机驱动程序确实会自动为您处理连接池。您可以在下面的StackOverflow链接中查找,以获得更多确认。OP也在问题中陈述了这一点。这意味着
客户端。connect
只应由服务器实例调用一次。在通过调用客户端成功检索到
,即应在整个应用程序实例中重复使用数据库
对象之后。connect数据库
对象。这可以通过使用该节点的模块模式轻松实现。JS提供。
我的建议是创建一个模块或一组模块,作为与数据库交互的单一联系点。在我的应用程序中,通常有一个依赖于本机驱动程序的模块,调用
require('mongodb')
。我的应用程序中的所有其他模块都不会直接访问数据库,但所有操作都必须由该数据库模块协调。
这将所有处理本机驱动程序的代码封装到单个模块或一组模块中。OP似乎认为我发布的简单代码示例存在问题,在我的示例中描述了“单个大闭包”的问题。这些都是非常基本的东西,所以我在这里对工作中的基本架构进行了澄清,但我仍然觉得没有必要更改任何代码。
OP似乎也认为可能在这里建立多个连接。这在这个设置中是不可能的。如果您像我上面建议的那样创建了一个模块,那么第一次调用
要求('./dbManager')
时,它将执行文件dbmanager.js
中的代码并返回module.exports
对象。导出对象被缓存,并且在每次后续调用要求('./dbManager')
时也会返回,但是,dbmanager.js
中的代码只会在第一次要求
时执行。
如果不想创建这样的模块,那么另一个选项是只导出传递给
客户机回调的
,并在整个应用程序的不同位置直接使用它。然而,我建议不要这样做,不管老年退休金计划有什么顾虑。数据库
。连接
类似的,可能重复的问题,除其他外:
如何在nodejs webapp中管理mongodb连接
这是我在运行上述程序时遇到的错误。有人解决了这个问题吗? 我尝试过改变Selenium和ChromeDriver的版本,但没有任何效果。
我们正在尝试使用nodejs/mongo原生驱动程序实现下面演示(幻灯片13-18)中概述的策略。 https://www.slideshare.net/mongodb/securing-mongodb-to-serve-an-awsbased-multitenant-securityfanatic-saas-application 总结: 从node.js.创建到mongoDB的连接池 对于租户
在nodejs中,根据每个请求打开mongodb连接,然后在回调中关闭它是一种好做法吗? 有人说,没有必要在每个请求上打开/关闭mongodb连接,因为一旦打开,就可以共享一个连接池。 问题是如何维护和共享该池?猫鼬已经自动做到了吗? 尤其是在mongodb超时或断开连接时,是否需要重新连接? 我在这里发现了相互矛盾的答案:是否根据请求关闭mongodb连接 我读到的几乎所有在线doc nodej
问题内容: 我正在使用datastax Java驱动程序3.1.0连接到cassandra集群,而我的cassandra集群版本是2.0.10。 下面是我用来连接cassandra集群的单例类。 首先需要使用哪些设置来连接本地cassandra节点,如果它们已关闭,则仅与远程节点通信。我的池配置选项也就在这里,上面的代码中正在使用该选项? 问题答案: 默认情况下,datastax驱动程序将仅连接到
我们有一个复制设置,其中主节点,辅助节点和仲裁节点运行mongodb社区服务器v3.4.16。 我们正在使用jasperserver从mongoDB数据库生成100个报告。 最近,我们在连接到mongodb服务器时开始面临连接重置问题,因为报告会随机失败。 应用程序(jasperserver)和mongodb在同一个网络中,它们之间没有防火墙。 有人能提供任何指导来进一步调查根本原因,以便解决问题
null 我确信我已经在127.0.0.1:27017启动了数据库服务,并且可以用shell和非异步方法连接。错误: PrimaryServerSelector没有从群集描述中选择服务器ClusterDescription{type=unknown,connectionmode=single,all=[ServerDescription{address=localhost:27017,type=u