我试图了解如何在节点应用程序中维护mongo客户端。我首先想到的是在每个单个集合检索上创建一个客户端。像这样:
const getCollection = (collectionName) => {
return MongoClient.connect(url, {useNewUrlParser: true, useUnifiedTopology: true})
.then((client) => {
const database = client.db(databaseName);
return database.collection(collectionName);
})
.catch((err) => {
console.log(err);
});
};
然后将返回的promise用于查询。像这样:
const executeFind = (collectionName, query, projection, skip, limit) => {
return getCollection(collectionName)
.then(collection => {
return collection.find(query, {projection: projection})
.skip(skip)
.limit(limit)
.toArray();
})
.catch((err) => {
console.log(err);
});
};
这种方法的问题是,在运行应用程序时,与mongo的打开连接的数量迅速增加,从而导致数据库操作和大量警报出现问题。
我认为连接增加的可能原因:
maxPoolSize=5
添加到URL。还向poolSize: 5
添加options
( MongoClient 的connect
函数的第二个参数。连接数仍会中断。close()
进行连接。但是无论如何,在close()
返回结果之后,我试图将代码重写为collection.find()
客户端。我得到Cannot use a session that has ended
除了这些之外,我没有其他想法可以以一种在资源分配/运行方面高效的方式来维护mongo客户端。我想听到两个答案:
答案 0 :(得分:0)
MongoClient.connect(url, {
poolSize: 10
// other options can go here
}, function(err, db) {
global.mongodb = db;
});
答案 1 :(得分:0)
我可以部分回答我的问题。
我可以使用client.close()
解决连接增加的问题。主要问题似乎是承诺没有兑现await
,因此close()
导致了意外的行为(close()
有时在实际调用查询之前发生,并导致{{1} }错误)。
上述方法(每次通话都打开和关闭连接)的问题在于速度很慢。
仍在寻找有关最佳维护客户的一般答案。
更新
我终于找到了一种解决方案,该解决方案不会大量打开连接,而且效果最佳。
此处的技巧是在将设置数据库对象的数据访问层(或数据库代码所在的位置)中声明并调用异步函数。像这样:
session already closed
然后只需在各处重用数据库对象,就像这样:
let database;
(async () => {
const client = await MongoClient.connect(url, {poolSize: 150, useNewUrlParser: true, useUnifiedTopology: true});
database = client.db(databaseName);
})();
池和连接的打开/关闭由database.collection(collectionName).insertMany(documents);
处理。就最佳性而言,它的速度更快(如预期)。不确定是否可以在dao中调用全局数据库或立即函数(不过,由于文件是通过client
导入的,因此不应多次调用)是最佳实践,但确实可以解决问题。