使用node-mongodb-native时如何保持DRY
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){ ... }) }) }) })
但是我们不会每次写db.open的时候都要做点什么,但是我们必须确保db在我们使用的时候已经打开了。
我们仍然不喜欢每次在相同的代码中处理错误。
我们也可以重用这个集合。
像这样
errorHandledDB.doSomething1("book",... function(result){ errorHandledDB.doSomething2("book",...function(result){ ... }) })
我使用mongodb实现了一个服务器应用程序进行日志logging。 我使用一些提供者类来实现数据访问,如示例中所示。
provider.filelog.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); }); } }); } }); };
由于我使用Grasshopper作为我的http中间件,我可以使用由gh提供的DIfunction轻松地注入提供程序:
server.js
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 });
在每个控制器function中访问提供者现在变得轻而易举:
gh.get('/serve', function() { this.providers.filelog.findAll(function(err, res) { // access data here }); });
这个实现对于Grasshopper是非常特殊的(因为它使用DI),但是我想你会明白的。 我也使用express和mongoose实现了一个解决scheme,你可以在这里find它。 这个解决scheme比使用本地驱动程序要简单一些,因为它暴露了用于数据库的模型。
更新
只是为了这个原因:如果你真的想坚持DRY原则,不要自己动手修改ORM实现并使用Mongoose 。 如果你需要像Map / Reduce这样的特殊function,你仍然可以使用本地驱动程序(Mongoose在其上构build)。
回答我自己的问题。 因为没有更好的select,我自己做,我开始一个项目来简化它,检查节点mongoskin 。
我在这里理论上讲话,不问Mongo。
我会build议你尝试build立一种包装。
一个数据访问层或至less是模型,这一切都取决于你的架构和需求,这是你的一面。
只需要用一层抽象命令来包装对mongodb的访问,而不是编写一个抽象模型对象,所有其他的模型对象都会inheritance它,并且会自动为你从mongo数据库中取出的logging属性设置所有的getter和setter。
为了更新你只需要给它一个保存方法,迭代并保存对它所做的所有更改。
由于这不是一个关系,我不知道这是否适合您的devise,这个模型在这里可能没有用处。
希望这有助于, 祝你好运!