当前位置: 首页 > 知识库问答 >
问题:

连接到express.js中的MongoDB本地驱动程序

穆俊杰
2023-03-14

我在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()等(在函数中执行的任何操作都由您来实现)。


共有3个答案

梁渊
2023-03-14

我只是想我会添加我自己的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页)中介绍了这种方法,这是值得称赞的

公孙慎之
2023-03-14

正如公认的答案所说——您应该只为所有传入请求创建一个连接并重用它,但答案缺少解决方案,它将创建和缓存连接。我编写了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来解决此问题。

希望你觉得有用。

邓昊天
2023-03-14

如何连接到数据库?

要使用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连接到数据库。导出在数据库上运行的createUserdeleteUser等功能,然后导出如下功能:

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