第十二步:数据库模式
第十二步:数据库模式
在根目录新建目录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);
一个模式(schema)是你的MongoDB数据库中的数据的一个表示,你能强迫某些字段必须为特定的类型,甚至决定该字段是否必需、唯一或者仅包含指定的元素。
和抽象的模式相比,一个模型(model)是和实践更接近的对象,包含添加、删除、查询、更新数据的方法,在上面,我们创建了一个Character模型并将它暴露出来。
注意:为什么这个教程仍然使用MongoDB?为什么不使用MySQL、PostgreSQL、CouchDB甚至RethinkDB?这是因为对于要构建的应用来说,我并不真正关心数据库层到底是什么样的。我更关注在前端的技术栈,因为这是我最感兴趣的部分。MongoDB也许并适合所有的使用场景,但它是一个合适的通用数据库,并且过去3年来我和它相处良好。
这里大多数字段都能自我解释,不过random
和voted
也许需要更多解释:
random
– 从[Math.random(), 0]
生成的包含两个数字的数组,这是一个MongoDB相关的地理标记,为了从数据库随机抓取一些角色,我们将使用$near
操作符,我是从StackOverflow上Random record from MongoDB学到这个技巧。voted
– 一个布尔值,为确定角色是否已被投票。如果不设置的话,人们可能会给同一角色反复刷票,现在当请求两个角色时,只有那些没有被投票的角色会被获取。即使有人直接使用API,已投票的角色也不会再次被投票。
回到server.js,在文件开头添加下面的代码:
var mongoose = require('mongoose');
var Character = require('./models/character');
为了保证一致性和系统性,我经常按照下面的顺序导入模块:
- 核心Node.js模块——path、querystring、http
- 第三方NPM库——mongoose、express、request
- 应用本身文件——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时特别有用。
现在让我们将它导入到server.js中:
var config = require('./config');
在终端中打开一个新的标签并运行mongod
。
更多建议: