关于NodeJs为什么要用mongoose操作mongodb
发布于 12 年前 作者 kimady 72042 次浏览 最后一次编辑是 8 年前

很多nodejs的新手都是直接用mongodb本身直接操作数据库,我之前也是如此

不知道大家有没有遇到过这个错误: Error: db object already connecting, open cannot be called multiple times

也许你会说是异步写得不好,但是就算异步写得再好,也逃避不了这个错误 因为无论如何,都要用到db.open();这东西,而且访问完毕还得db.close();

于是就有一个问题:刷新得太快,或者多个用户同时访问数据库,数据库没来得及关闭,那个Error就会出现

可以做一下实验,在访问数据库的页面按住F5,就会很容易看到在页面上或者控制台上抛出的Error勒

用mongoose就不会出现这错误勒,因为一旦连接好数据库,db就会处于open状态,不存在访问时要打开,然后又要关闭的规则,然后我果断把所有mongodb部分改为mongoose,按住F5毫无压力啊,而且尼玛代码又短了一大截!

前后代码对比一下:

之前每次操作要open:

User.get = function get(username, callback) {
  mongodb.open(function(err, db) {
    if (err) {
      return callback(err);
    }
    //读取 users 集合
    db.collection('users', function(err, collection) {
      if (err) {
        mongodb.close();
        return callback(err);
      }
      //查找 name 属性为 username 的文档
      collection.findOne({name: username}, function(err, doc) {
        mongodb.close();
        if (doc) callback (err, doc);
        else callback (err, null);
      });
    });
  });
};

现在,建立好mongoose对象模型后只需几行代码即可实现相同的功能:

User.get = function get(username, callback) {
  users.findOne({name:username}, function(err, doc){
    if (err) {
      return callback(err, null);
    }
    return callback(err, doc);
  });
};
27 回复

mongo原生的library也可以不close啊

哎呀,我也觉得,既然node.js是单进程的,db何必要close了,一直保持open也不会有太大问题

不太明白您的意思。。具体在nodejs下要怎么搞?

@kimady 举一种最简单的做法:把 mongodb.open 写在最外围

mongodb.open(function(err, db) {
  // 把所有其他代码都包含在这个里面,并且丢掉 mongodb,只使用 db
});

@XiongLiding 哦,但是我那个项目东西有点多,用的是express,这样做的话全部都挤到一起了不太好吧?而且好像挺难弄的~

mongoose 不用schema怎么查数据?

有用到schema的,只是没贴上去:

var userObj = new Schema({
  name: {type: String, index: {unique: true}},
  nick: String,
  password: String,
  email: String,
  submit: Number,
  solved: Number,
  regTime: String,
  privilege: String
});

mongoose.model('users', userObj);
var users = mongoose.model('users');

@kimady 还有原生的libray每步操作都是回调方法,嵌套会很多,可以用step或者async做control flow,代码看上去会舒服很多~

@ltebean 谢谢你哈,我慢慢看:)

对呀,呵呵~

请问如何判断db是否已经Open

User.get = function get(username, callback) { … } 新手问一下 这里的 callback 参数是指什么? 在哪用的? callback 是具体的在哪定义的。 没搞懂mongoose的callback 是指什么? 还是mongo的?

callback是你自己定义的回调函数,用于响应get函数的处理结果,因为get函数是异步的,等get函数出结果了,get函数就调用callback(err, result)

要是用mongodb 需要怎么解决啊

在express3中mogondb一般是怎么用?

@kimady node.js单进程,跟db要不要close没有1毛钱关系

自己写mongodb是挺蛋疼的

说到心里去了,曾经的同病相怜者飘过。

node-native-mongodb 要比你所谓的mongoose好用效率几十倍,

mongoose说到底就是纯面向对象和纯关系数据库程序员,一时转换不到动态类型编程的路子上的过渡口而已。

native 的话不要 close 就好了。不过用 mongoose 主要是方便。

楼主不用连接池?每次打开关闭,你想搞死数据库啊😱

请教个问题,db一直open失败,不知道什么原因? 错误打印如下: open err:{ [MongoError: connect UNKNOWN] name: ‘MongoError’, message: ‘connect UNKNOWN’ }

// 源代码如下:

var mongoose = require(‘mongoose’); var mongodb = require(‘mongodb’); var util = require(‘util’);

var server = new mongodb.Server(‘localhost’, 27017, {auto_reconnect:true}); var db = new mongodb.Db(‘account’, server, {safe:true});

db.open(function(err, db){ if (err) { console.log(‘open err:’+ util.inspect(err)); return ; } console.log(‘db opened.’); });

我用 mongo localhost/account命令连接上去,数据库服务都是正常的,但是node.js里就是连接不上,哪位帮我解答一下?

jugglingdb 这个有人用过吗?

深有体会,我用的是connect-mongo模块,当我用压测工具(比如workbench去跑并发的时候),直接就跪了,报错如下:

Error: Can’t set headers after they are sent. at validateHeader (_http_outgoing.js:489:11) at ServerResponse.setHeader (_http_outgoing.js:496:3) at ServerResponse.header (/Users/xjnotxj/Program/NodeJsProject/PhotoFlowDisplayModule/node_modules/express/lib/response.js:730:10) at ServerResponse.send (/Users/xjnotxj/Program/NodeJsProject/PhotoFlowDisplayModule/node_modules/express/lib/response.js:170:12) at ServerResponse.json (/Users/xjnotxj/Program/NodeJsProject/PhotoFlowDisplayModule/node_modules/express/lib/response.js:256:15) at /Users/xjnotxj/Program/NodeJsProject/PhotoFlowDisplayModule/routes/photo.js:169:36 at /Users/xjnotxj/Program/NodeJsProject/PhotoFlowDisplayModule/models/post.js:105:24 at Db.collection (/Users/xjnotxj/Program/NodeJsProject/PhotoFlowDisplayModule/node_modules/mongodb/lib/db.js:466:27) at /Users/xjnotxj/Program/NodeJsProject/PhotoFlowDisplayModule/models/post.js:102:12 at /Users/xjnotxj/Program/NodeJsProject/PhotoFlowDisplayModule/node_modules/mongodb/lib/db.js:238:5 at Server.connectHandler (/Users/xjnotxj/Program/NodeJsProject/PhotoFlowDisplayModule/node_modules/mongodb/lib/server.js:324:7) at Object.onceWrapper (events.js:316:30) at emitOne (events.js:120:20) at Server.emit (events.js:210:7) at /Users/xjnotxj/Program/NodeJsProject/PhotoFlowDisplayModule/node_modules/mongodb-core/lib/topologies/server.js:300:14 at /Users/xjnotxj/Program/NodeJsProject/PhotoFlowDisplayModule/node_modules/mongodb-core/lib/connection/pool.js:469:18

回到顶部