## 第十二步:数据库模式
在根目录新建目录models,然后进入目录并新建文件*character.js*:
~~~
var mongoose = require('mongoose');
var characterSchema = new mongoose.Schema({
characterId: { type: String, unique: true, index: true },
name: String,
race: String,
gender: String,
bloodline: String,
wins: { type: Number, default: 0 },
losses: { type: Number, default: 0 },
reports: { type: Number, default: 0 },
random: { type: [Number], index: '2d' },
voted: { type: Boolean, default: false }
});
module.exports = mongoose.model('Character', characterSchema);
~~~
![](https://box.kancloud.cn/2015-09-14_55f643b4dab4b.jpg)
一个模式(schema)是你的MongoDB数据库中的数据的一个表示,你能强迫某些字段必须为特定的类型,甚至决定该字段是否必需、唯一或者仅包含指定的元素。
和抽象的模式相比,一个模型(model)是和实践更接近的对象,包含添加、删除、查询、更新数据的方法,在上面,我们创建了一个Character模型并将它暴露出来。
> 注意:为什么这个教程仍然使用MongoDB?为什么不使用MySQL、PostgreSQL、CouchDB甚至[RethinkDB](http://rethinkdb.com/)?这是因为对于要构建的应用来说,我并不真正关心数据库层到底是什么样的。我更关注在前端的技术栈,因为这是我最感兴趣的部分。MongoDB也许并适合所有的使用场景,但它是一个合适的通用数据库,并且过去3年来我和它相处良好。
这里大多数字段都能自我解释,不过`random`和`voted`也许需要更多解释:
* `random` – 从`[Math.random(), 0]`生成的包含两个数字的数组,这是一个MongoDB相关的[地理](http://docs.mongodb.org/manual/applications/geospatial-indexes/)标记,为了从数据库随机抓取一些角色,我们将使用[`$near`](http://docs.mongodb.org/manual/reference/operator/query/near/)操作符,我是从StackOverflow上[Random record from MongoDB](http://stackoverflow.com/questions/2824157/random-record-from-mongodb)学到这个技巧。
* `voted` – 一个布尔值,为确定角色是否已被投票。如果不设置的话,人们可能会给同一角色反复刷票,现在当请求两个角色时,只有那些没有被投票的角色会被获取。即使有人直接使用API,已投票的角色也不会再次被投票。
回到server.js,在文件开头添加下面的代码:
~~~
var mongoose = require('mongoose');
var Character = require('./models/character');
~~~
为了保证一致性和系统性,我经常按照下面的顺序导入模块:
1. 核心Node.js模块——path、querystring、http
2. 第三方NPM库——mongoose、express、request
3. 应用本身文件——controllers、models、config
最后,为链接到数据库,在依赖模块和Express中间件之间添加下面的代码,它将在我们启动Express app的时候发起一个到MongoDB的连接池:
~~~
mongoose.connect(config.database);
mongoose.connection.on('error', function() {
console.info('Error: Could not connect to MongoDB. Did you forget to run `mongod`?');
});
~~~
> 注意:我们将在config.js中设置数据库的hostname以避免硬编码。
在根目录新建另一个文件*config.js*:
~~~
module.exports = {
database: process.env.MONGO_URI || 'localhost'
};
~~~
它将使用一个环境变量(如果可用)或降级到localhost,这将允许我们在本地开发时使用一个hostname,而在生产环境使用另一个,同时无需修改任何代码。这种方法对于[处理OAuth客户端key和secret](https://github.com/sahat/hackathon-starter/blob/master/config/secrets.js)时特别有用。
现在让我们将它导入到server.js中:
~~~
var config = require('./config');
~~~
在终端中打开一个新的标签并运行`mongod`。
![](https://box.kancloud.cn/2015-09-14_55f643b558bcb.jpg)
- 前言
- 概述
- 第一步:新建Express项目
- 第二步:构建系统
- 第三步:项目结构
- 第四步: ES6速成教程
- 第五步: React速成教程
- 第六步:Flux架构速成教程
- 第七步:React路由(客户端)
- 第八步:React路由(服务端)
- 第九步:Footer和Navbar组件
- 第十步:Socke.IO – 实时用户数
- 第十一步:添加Character的组件
- 第十二步:数据库模式
- 第十三步:Express API 路由(1/2)
- 第十五步:Home组件
- 第十四步:Express API 路由(2/2)
- 第十六步:角色(资料)组件
- 第十七步:Top 100 组件
- 第十八步:Stats组件
- 第十九步:部署
- 第二十步: 附加资源
- 总结