首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >连接到Mongodb- express.js中的本机驱动程序

连接到Mongodb- express.js中的本机驱动程序
EN

Stack Overflow用户
提问于 2013-08-04 14:39:47
回答 3查看 7.3K关注 0票数 15

我在express.js应用程序中使用mongodb-本机驱动程序。我在数据库中有大约6个集合,所以我创建了6个js文件,每个文件都有一个作为javascript对象(例如function collection(){})的集合,以及处理这些集合上所有操作的原型函数。我觉得这是个很好的建筑。

但是我遇到的问题是如何连接到数据库?我应该在每个文件中创建一个连接并使用它们吗?,我认为这将是过度的,因为mongodb中的连接本机驱动程序创建了一个连接池,其中有几个是不合理的。

,那么我如何创建一个连接池,并在所有的collections.js文件中使用它呢?,我想让连接像它在猫鼬中实现的那样。让我知道,如果我的思维过程在架构的应用程序是错误的。

使用Mongoose可以解决这些问题,但是我在几个地方读过,它比本地驱动程序慢,而且我更喜欢没有模式的模型。

编辑:我用模型创建了一个模块。每个集合都在一个文件中,它将数据库作为参数。现在,在index.js文件中,我调用了数据库连接,并在从连接中获得数据库后保留了一个变量db。(我使用了自动重新连接功能,以确保连接没有丢失)。在同一个index.js文件中,我导出了如下所示的每个集合

代码语言:javascript
运行
复制
exports.model1 = require('./model1').(db)
exprorts.model2 = require('./model2').(db)

这确保了数据库部分仅在一个模块中处理,应用程序只调用每个model.js文件导出的函数,如save()fincdbyid()等(whatever you do in the function is upto you to implement)。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-08-04 21:39:13

如何连接到数据库?

为了使用MongoDB本机驱动程序进行连接,需要执行以下操作:

代码语言:javascript
运行
复制
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等),然后导出功能如下:

代码语言:javascript
运行
复制
module.exports = {
    createUser: function () { ; },
    deleteUser: function () { ; }
};

然后,您可以从另一个文件进行require,如下所示:

代码语言:javascript
运行
复制
var dbman = require('./dbmanager');

dbman.createUser(userData); // using connection established in `dbmanager.js`

编辑:,因为我们处理的是JavaScript和单个线程,本机驱动程序实际上会自动为您处理连接池。您可以在下面的StackOverflow链接中查找这一点,以获得更多的确认。“任择议定书”也在问题中说明了这一点。这意味着client.connect只应该被服务器的一个实例调用一次。在成功地从对database的调用中检索到client.connect对象之后,应该在应用程序的整个实例中重用该database对象。这很容易通过使用Node.JS提供的模块模式来实现。

我的建议是创建一个或多个模块集,作为与数据库交互的单一接触点。在我的应用程序中,我通常有一个依赖于本地驱动程序的模块,即调用require('mongodb')。我的应用程序中的所有其他模块都不会直接访问数据库,而是所有操作都必须由这个数据库模块协调。

这将处理本机驱动程序的所有代码封装到一个或多个模块中。OP似乎认为我发布的简单代码示例存在问题,在我的示例中描述了“单个大闭包”的问题。这都是非常基本的东西,所以我在这里添加对基本架构的澄清,但我仍然不觉得有必要修改任何代码。

OP似乎还认为在这里可以建立多个连接。这种设置是不可能的。如果像我前面建议的那样创建了一个模块,那么第一次调用require('./dbmanager')时,它将执行文件dbmanager.js中的代码并返回module.exports对象。导出对象被缓存,并在每次调用require('./dbmanager')时返回,但是,dbmanager.js中的代码将只执行第一个require

如果您不想创建这样的模块,那么另一种选择是只导出传递给client.connect回调的client.connect,并在整个应用程序的不同位置直接使用它。然而,我建议不要这样做,不管OPs有什么顾虑。

类似的、可能重复的堆栈溢出问题,除其他外:

票数 18
EN

Stack Overflow用户

发布于 2014-08-08 18:43:00

正如公认的答案所述-您应该只为所有传入请求创建一个连接并重用它,但是答案是缺少的解决方案,这将创建和缓存连接。我编写了快速中间件来实现这一目标-- 特快专递。乍一看,这个任务是微不足道的,大多数人使用这种代码:

代码语言:javascript
运行
复制
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一次来解决这个问题。

希望你觉得有用。

票数 2
EN

Stack Overflow用户

发布于 2014-08-21 01:52:28

我只是想为其他感兴趣或有问题的人添加我自己的MongoDB连接方法

此方法假定您不需要身份验证(我在本地主机上使用此方法)

身份验证仍然容易实现。

代码语言:javascript
运行
复制
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页)中对这种方法进行了研究。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18044113

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档