【Node.js】mongoose教程03--Schema与Model
GitHub源码链接:sodino#MongoDemo
理解Schema
传统的MySQL、Oracle等关系型数据库中,在存储数据之前,开发者必须道德为数据定义数据表,并且为该数据表定义一些字段,从而使数据模型得到实现。
可以说,在关系型数据库中,一个数据表就是一个数据架构。它预先定义了开发者可以使用的数据模型。
但MongoDB是面向文档的数据库,不是关系型数据库。被认为是无数据架构的。
然而数据架构仍然是有用的,可以使人以易读的方式来描述数据库中的数据内容,并为这些数据定义一些规则。
如Mongoose可以对Number
的数据设置最小值min
与最大值max
;可以对Date
设置默认值为当前时间;可以对String
设置存储为小写模式并去除头尾空白字符。
而以上所说的功能都在Mongoose的设计理念中,都由Schema
的定义来实现。
Schema的定义
在Sodino的MongoDemo工程中,需要对手机进行数据架构的定义。具体实现如下:
1 | // 准备工作 |
至此,对手机的Schema
定义完成。
当然,也可能通过Api对Schema进行动态扩展,如需要增加手机的颜色这一数据属性,则可以用如下代码实现:
1 | phoneSchma.add({color : 'string'}) |
Schema
中所支持的数据类型有:
- String
- Number
- Date
- Buffer
- Boolean
- Mixed
- Objectid
- Array
创建Model
下一步在代码中使用Schema
所定义的数据模型,需要将定义好的phoneSchema
转换为Model
。
可以使用mongoose.model(modelName, schema)
进行转换。
1 | var Phone = mongoose.model('Phone', phoneSchema); |
有Schema
后为什么还要有Model
呢?
在Mongoose的设计理念中,Schema
用来也只用来定义数据结构,具体对数据的增删改查操作都由Model
来执行。
就好比富士康用模具组装出一台手机后,当需要打电话时是用手机来打而不是用模具。
创建数据实例
Model
相当于数据的构造函数。当需要实例化出一个数据对象实例时,可以使用new
操作符来实现。
1 | var iPhoneSE = new Phone( |
在上面的代码中,数据的具体值以JSON对象的形式作为参数传入Phone
即构造出数据对象实例iPhoneSE
。
在sodino#MongoDemo示例代码中,Sodino使用了require(json.file.path)
来获取JSON对象再传参到Phone
的方式。简化了JavaScript的代码量。
1 | // raw.iPhoneSe.json与当前的js代码文件放于同一目录下 |
1 | // raw.iPhoneSe.json内容如下: |
Model实例方法
可以为Model
的实例添加自定义方法,作法也很简单,只要将自定义的方法添加到Schema.methods
即可。
可以设想这样的功能,Phone
的内容很多,但客户最关心哪个手机价格是多少,那么可以添加一个实例方法printBrief()
用来打印出这两个信息就好了。
如下代码所示:
1 | var mongoose = require('mongoose'); |
printBrief()
的使用方法如下:
1 | var iPhoneSE = new Phone(raw); |
控制台输出为:
1 | iPhone SE ¥ 4999 |
需要注意的是,Model实例方法只能被Model的实例调用,不能被Model直接调用,否则会抛出is not a function
异常。这相当于Java的非静态方法不能被Class直接调用。异常如下所示:
1 | TypeError: Phone.printBrief is not a function at Query.<anonymous> (D:\desk\JavaScript\MongoDemo\app.js:427:14) at D:\desk\JavaScript\MongoDemo\node_modules\kareem\index.js:177:19 at D:\desk\JavaScript\MongoDemo\node_modules\kareem\index.js:109:16 at _combinedTickCallback (node.js:370:9) at process._tickCallback (node.js:401:11) |
Model静态方法
与实例方法相对应的是静态方法。只要在Schema.statics
中添加新声明的方法即可。
可以设想这样的功能,想查询一下Phone
到底存储了多少个手机型号,可以定义一个静态方法printCount()
,代码如下:
1 | var mongoose = require('mongoose'); |
调用方法如下:
1 | Phone.printCount(); |
控制台打印如下:
1 | ---printCount()----------------------------- phone count=5 |
说了这么多,接下来的文章开始介绍数据库的增删改查了哈…
下一篇:mongoose教程–存储
相关链接
Mongoose Quick Start v4.4.19
Mongoose Schemas v4.4.19