Back-End与Database如何通信,mongoose与mongodb模块的区别


  上一篇博客我们介绍了Client与Back-End如何通信,成功打通了客户端到服务器端的。
  现在我们来研究一下服务器内部的Back-End与Database之间的通信方式(初衷),以及nodejs服务端常用的2个操作和管理MongoDB的模块的对比(重点)。
  下面关于mongoose和mongodb的对比中包含了Back-End与Database建立通信的方式,因此我们不单独拿出来讲。
  简单说一下的话,就是数据库开一个默认监听端口出来,然后Back-End端调用接口去和默认监听端口建立连接。(通信内部协议我们不去深入。)

Ok,现在开始分析mongoose和mongdb模块。

一.初步分析mongoose和mongodb模块

关于mongoose的详情:
  mongoose 是个 odm。odm 的概念对应 sql 中的 orm。也就是 ruby on rails 中的 activerecord 那一层。orm 全称是 Object-Relational Mapping,对象关系映射;而 odm 是 Object-Document Mapping,对象文档映射。
  它的作用就是,在程序代码中,定义一下数据库中的数据格式,然后取数据时通过它们,可以把数据库中的 document 映射成程序中的一个对象,这个对象有 .save .update 等一系列方法,和 .title .author 等一系列属性。在调用这些方法时,odm 会根据你调用时所用的条件,自动转换成相应的 mongodb shell 语句帮你发送出去。自然地,在程序中链式调用一个个的方法要比手写数据库操作语句具有更大的灵活性和便利性。

用一段代码来说明mongoose的作用:

var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost:27017/myproject');
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function() {
  // we're connected!
  var userSchema=new mongoose.Schema({
    user:{ username:String,
         password:String
         },
    contents:{
         title:String,
         poster:String,
         post:String,
         time:Date,
         imgs:[],
         comment:[]
     }
    });
    var User = mongoose.model('user', userSchema);
    var Frank = new User({
        user:{ username:'Frank',
            password:'12345678'
            },
    });
    console.log(Frank.user);
    Frank.save(function (err) {
        console.log('保存成功');
      });
});

我们将数据,也就是Frank的个人信息保存mongodb://localhost:27017/myproject的user model中。
  这句话的直观意思是:我们将一个document,保存到myproject数据库的users collection中。
  不知道聪明的你发现没有?
  此处最巧妙的地方在于,model自动为我们创建了users这个collection。
  所以可以理解model为document+collection的集大成者。
  由此可见,mongoose是一个elegant mongodb object modeling for nodejs。
那么如何理解mongodb这个模块,它和mongoose有何异同?

看下下面这段代码:

var MongoClient = require('mongodb').MongoClient,
    assert=require('assert');
var url = 'mongodb://localhost:27017/myproject';
MongoClient.connect(url,function(err,db){
    assert.equal(null,err);
    console.log("成功连接到服务器");
    insertDocuments(db,function(){
        db.close();
    });
   // db.close();
});
var insertDocuments = function(db,callback){
    var collection = db.collection('documents');
    collection.insertMany([
        {a:1},
        {a:2},
        {a:3}
    ],function(err,result){
        assert.equal(err,null);
        assert.equal(3,result.result.n);
        assert.equal(3,result.ops.length);
        console.log("成功插入3个文档到集合!");
        callback(result);
    });
}

聪明的你一下就看出来了,mongodb模块中的命令更像是mongodb-shell中的命令。
  所以这也是mongdb模块被称作MongoDB数据库的驱动的原因,说白了就是官方提供的一种管理和操作MongoDB数据库的nodejs接口。
mongodb是一个MongoDB官方为nodejs语言用户开发的本地驱动,除了mongodb这个nodejs驱动,MongoDB还提供了众多语言的驱动,包括Python,Php等等。

总结一下:

MongoDB:mongodb核心服务启动:mongod命令,开放27017端口允许建立连接.
mongodb package:管理数据库开关,collections和documents等,通过27017端口连接数据库。
mongoose package:数据库中集合的创建和管理,通过27017端口连接数据库。

PS:可以使用mongo命令开启MongoDB shell窗口,直接对话数据库

其实到这里还是对二者有些难以区分,请看这句话:

Let's face it, writing MongoDB validation, casting and business logic boilerplate is a drag. That's why we wrote Mongoose.

从这句话我们可以分析出来,如果只是使用mongodb的话,我们可能需要对数据进行验证,计算以及写复杂的业务逻辑,说白了就是处理collections里的documents比较麻烦,而moogose正好解决了这个问题。

二.进阶分析mongoose和mongodb模块

下面引用一段stackoverflow上的大神一段话:

I assume you already know that MongoDB is a NoSQL database system which stores data in the form of BSON documents. Your question, however is about the packages for Node.js.
In terms of Node.js, mongodb is the native driver for interacting with a mongodb instance and mongoose is an Object modeling tool for MongoDB.
Mongoose is built upon the MongoDB driver to provide programmers with a way to model their data.
EDIT: I do not want to comment on which is better, as this would make this answer opinionated. However I will list some advantages and disadvantages of using both approaches.
Using Mongoose, a user can define the schema for the documents in a particular collection. It provides a lot of convenience in the creation and management of data in MongoDB. On the downside, learning mongoose can take some time, and has some limitations in handling schemas that are quite complex.
However, if your collection schema is unpredictable, or you want a Mongo-shell like experience inside Node.js, then go ahead and use the MongoDB driver. It is the simplest to pick up. The downside here is that you will have to write larger amounts of code for validating the data, and the risk of errors is higher.

他给出了mongoose和mongodb的适用场景和优缺点。

关键处已做加粗标记,但是为了对比清晰些,这里我再列个表格。

Tables 数据可预测性 优点 缺点
mongoose 可预测 creation and management of data handling schemas that are quite complex
mongodb 不可预测 Mongo-shell like experience write larger amounts of code for validating the data

所以由此可以看出,我们应该结合具体的业务场景,在二者之间做一个合适的选择。

三.思考与总结

1.个人认为,数据类型一般来说都是可预测的。

举个简单的例子:用户的账号和密码,一般来说都是字符串类型。

此时使用mongoose就可以清晰得定义users的username和password为string类型;若不预先定义,那么需要去判断username和password是否符合存储要求。

2.这有些类似于关系型数据库中的数据类型定义,为什么要在Back-end定义数据类型呢?不能像关系型数据库一样,在数据库中定义表的字段时候声明数据类型吗?

答案是不行。

因为mongodb中的所有数据都是binary的,因此需要mongoose去做一个数据类型的定义,主要方法就是将document映射成一个对象。

3.二者都是通过MongoDB的27017默认监听端口进行连接,从而进行后续的集合和文档的定义,创建等操作。

道路是曲折的,但前途是光明的!

努力成为优秀的大前端工程师!

参考:
https://segmentfault.com/q/1010000010864304?_ea=2441566
https://stackoverflow.com/questions/28712248/difference-between-mongodb-and-mongoose?answertab=votes
https://gxnotes.com/article/168202.html
https://github.com/alsotang/node-lessons/tree/master/lesson15

期待和大家交流,共同进步,欢迎大家加入我创建的与前端开发密切相关的技术讨论小组:

努力成为优秀前端工程师!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,736评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,167评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,442评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,902评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,302评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,573评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,847评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,562评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,260评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,531评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,021评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,367评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,016评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,068评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,827评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,610评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,514评论 2 269

推荐阅读更多精彩内容