使用node mongodb native时如何保持干燥
但我们不会每次想做某事时都编写db.open,但我们必须确保在使用它时db已经打开 我们仍然不喜欢在同一代码中每次都处理错误 我们还可以重用集合 就这样使用node mongodb native时如何保持干燥,mongodb,node.js,Mongodb,Node.js,但我们不会每次想做某事时都编写db.open,但我们必须确保在使用它时db已经打开 我们仍然不喜欢在同一代码中每次都处理错误 我们还可以重用集合 就这样 db.open(function(err,db){ //handle error db.collection("book",function(err, collection){ //handle error collection.doSomething1(... function(err, result){
db.open(function(err,db){
//handle error
db.collection("book",function(err, collection){
//handle error
collection.doSomething1(... function(err, result){
//handle error
collection.doSomething2(... function(err, result){
...
})
})
})
})
我使用mongodb实现了一个用于日志记录的服务器应用程序。我使用一些提供程序类实现了数据访问,如示例所示 provider.filelog.js
errorHandledDB.doSomething1("book",... function(result){
errorHandledDB.doSomething2("book",...function(result){
...
})
})
由于我使用的是http中间件,因此我可以使用gh提供的DI功能轻松地注入提供者:
server.js
var Db= require('mongodb/db').Db,
ObjectID= require('mongodb/bson/bson').ObjectID,
Server= require('mongodb/connection').Server,
log = require('lib/common').log;
FilelogProvider = function (host, port, database) {
this.db= new Db(database, new Server(host, port, {auto_reconnect: true}, {}));
this.db.open(function(){});
};
FilelogProvider.prototype.getCollection= function(callback) {
this.db.collection('filelogs', function(error, log_collection) {
if (error) callback(error);
else {
log_collection.ensureIndex([[ 'created', 1 ]], false, function(err, indexName) {
if (error) callback(error);
callback(null, log_collection);
});
}
});
};
FilelogProvider.prototype.findAll = function(callback) {
this.getCollection(function(error, log_collection) {
if (error) callback(error);
else {
log_collection.find(function(error, cursor) {
if (error) callback(error);
else {
cursor.toArray(function(error, results) {
if (error) callback(error);
else callback(null, results);
});
}
});
}
});
};
访问每个控制器功能中的提供程序现在是轻而易举的事:
gh.addToContext({
providers: {
filelog: new FilelogProvider(conf.mongodb_host, conf.mongodb_port, conf.mongodb_database),
status: new ServerstatusProvider(conf.mongodb_host, conf.mongodb_port, conf.mongodb_database)
},
log: log
});
这个实现非常特定于Grasshopper(因为它使用DI),但我想你会明白的。我还使用express和mongoose实现了一个解决方案。此解决方案比使用本机驱动程序更简洁,因为它公开了用于数据库的模型
更新
仅仅是为了它:如果你真的想坚持干涸的原则,停止自己修补ORM实现并使用它。如果您需要Map/Reduce之类的特殊功能,您仍然可以使用本机驱动程序(Mongoose就是基于它构建的)。我在这里讲的是理论上的,与mongo无关 我建议你试着做一种包装 数据访问层或至少是模型,这取决于您的体系结构和需求, 这是站在你这边的 只需使用一层抽象命令包装对mongodb的访问,然后编写一个抽象模型对象,所有其他模型对象将从中继承,并将自动为从mongodb提取的记录的属性设置所有getter和setter 对于更新,您只需给它一个save方法,该方法迭代并保存对它所做的所有更改 因为它不是关系型的,我不知道这是否适合您的设计,所以该模型在这里可能没有用处
希望这有帮助,祝你好运回答我自己的问题。因为没有更好的选择,我自己做,我启动一个项目来简化它,检查。但是如果在Callack中执行另一个操作,getCollection将调用两次。这与我的实现无关,但是您可以引入某种缓存来只提取一次集合(例如,将收藏保存给提供商的成员)。首次提取后,您只需检查成员是否为null并返回,而不是重新提取集合。@guilin:您可以获取集合并将其保存到this.collection,然后在其他任何地方使用this.collection。在类中创建一个帮助函数,该函数执行
if(this.collection!=“undefined”){//获取集合并保存到this.collection}
。然后必须在每个方法的顶部调用该帮助程序
gh.get('/serve', function() {
this.providers.filelog.findAll(function(err, res) {
// access data here
});
});