Mongoose.Scema基础学习
名词解释
-
Schema
: 一种以文件形式存储的数据库模型骨架,不具备数据库的操作能力 -
Model
: 由Schema发布生成的模型,具有抽象属性和数据库操作能力 -
Entity
: 由Model创建的实例,也能操作数据库
Schema、Model、Entity 的关系请牢记,Schema 生成 Model,Model 创造 Entity,Model 和 Entity 都可对数据库操作造成影响,但 Model 比 Entity 更具操作性。
在学习 mongodb 的过程中需要熟悉几个名词以及他们对应的关系型数据库名词。
关系型数据库 | mongodb |
---|---|
table | collection |
row | document |
column | index |
table joins | populate |
primary key | _id |
Schema
定义 Schema
mongoose 中任何任何事物都是从 Schema 开始的。每一个 Schema 对应 MongoDB 中的一个集合(collection)。Schema 中定义了集合中文档(document)的样式。
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var blogSchema = new Schema({
title: String,
author: String,
body: String,
comments: [{ body: String, date: Date }],
date: { type: Date, default: Date.now },
hidden: Boolean,
meta: { votes: Number, favs: Number}
});
如果之后想要在Schema
中添加键,可以使用Schema#add
方法。
Schema.Type
- String
- Number
- Date
- Buffer
- Boolean
- Mixed
- Objectid
- Array
expmale:
var Schema = new Schema({
name: String,
binary: Buffer,
isDeleted: Boolean,
updated: Date,
age: Number,
mixed:Schema.Types.Mixed,
_id:Schema.Types.ObjectId, //主键
_fk:Schema.Types.ObjectId, //外键
array: [],
arrOfString: [String],
arrOfNumber: [Number],
arrOfDate: [Date],
arrOfBuffer: [Buffer],
arrOfBoolean: [Boolean],
arrOfMixed: [Schema.Types.Mixed],
arrOfObjectId: [Schema.Types.ObjectId],
nested:{
stuff: String,
}
})
Buffer 和 ArrayBuffer 是 Nodejs 两种隐藏的对象,相关内容请查看 NodeJS-API
Schema.Type.Mixed
Schema.Types.Mixed 是 Mongoose 定义个混合类型,该混合类型如果未定义具体形式
var AnySchema = new Schema({any:{}})
var AnySchema = new Schema({any:Schema.Types.Mixed})
混合类型因为没有特定约束,因此可以任意修改,一旦修改了原型,则必须调用markModified()
person.anything = {x:[3,4,{y:'change'}]}
person.markModified('anything') //传入anything,表示该属性类型发生变化
person.save()
ObjectId
主键,一种特殊而且非常重要的类型,每个 Schema 都会默认配置这个属性,属性名为_id,除非自己定义,方可覆盖
var mongoose = require('mongoose')
var ObjectId = mongoose.Schema.Types.ObjectId
var StudentSchema = new Schema({}) //默认会有_id:ObjectId
var TeacherSchema = new Schema({id:ObjectId}) //只有id:ObjectId
Array
Array在JavaScript编程语言中并不是数组,而是集合,因此里面可以存入不同的值,以下代码等价:
var ExampleSchema1 = new Schema({array:[]})
var ExampleSchema2 = new Schema({array:Array})
var ExampleSchema3 = new Schema({array:[Schema.Types.Mixed]})
var ExampleSchema4 = new Schema({array:[{}]})
附言
Schema
不仅定义了文档结构和使用性能,还可以有扩展插件、实例方法、静态方法、复合索引、文档生命周期钩子
Schema
可以定义插件,并且插件具有良好的可拔插性, Schema#add
, Schema#set
, Schema#static
...
Schema 扩展
实例方法
我们创造的Schema不仅要为后面的Model和Entity提供公共的属性,还要提供公共的方法。
var PersonSchema = new Schema({name:String,type:String})
//查询类似数据
PersonSchema.methods.findSimilarTypes = function(cb){
return this.model('Person').find({type:this.type},cb)
}
var PersonModel = mongoose.model('Person',PersonSchema)
var krouky = new PersonSchema({name:'krouky',type:'前端工程师'})
krouky.findSimilarTypes(function(err,persons){
//persons中就能查询到其他前端工程师
})
静态方法
静态方法可以在 model 层使用
PersonSchema.statics.findByName = function(name,cb){
this.find({name:new RegExp(name,'i'),cb})
}
var PersonModel = mongoose.model('Person',PersonSchema)
PersonModel.findByName('krouky',function(err,persons){
//找到所有名字叫krouky的人
})
索引
索引或者复合索引能让搜索更加高效,默认索引就是主键索引
ObjectId
,属性名为_id
,或者使用index: true
来创建索引。
虚拟属性
Schema
中如果定义了虚拟属性,那么该属性将不写入数据库,例如
var PersonSchema = new Schema({
name:{
first:String,
last:String
}
})
var PersonModel = mongoose.model('Person',PersonSchema)
var krouky = new PersonModel({
name:{first:'krouky',last:'han'}
})
全名:
console.log(krouky.name.first + ' ' + krouky.name.last);
这个时候就可以使用虚拟属性
PersonSchema.virtual('name.full').get(function(){
return this.name.first + ' ' + this.name.last
})
那么就能用krouky.name.full
来调用全名了,反之如果知道full
,也可以反解first
和last
属性
PersonSchema.virtual('name.full').set(function(name){
var split = name.split(' ')
this.name.first = split[0]
this.name.last = split[1]
});
var PersonModel = mongoose.model('Person',PersonSchema)
var krouky = new PersonModel({})
krouky.name.full = 'krouky han' //会被自动分解
console.log(krouky.name.first) //krouky
配置项
在使用new Schema(config)时,我们可以追加一个参数options来配置Schema的配置,形如:
var ExampleSchema = new Schema(config,options)
或者使用
var ExampleSchema = new Schema(config)
ExampleSchema.set(option,value)
以下是官网目前提供的所有Schema.options
有效的配置项
详细使用根据链接查看官方文档
-
autoIndex
自动创建索引,在应用程序启动时,Mongoose会ensureIndex
为您声明的每个索引发送一个命令Schema
。在Mongoose v3中,background
默认情况下会创建索引。如果要禁用自动创建功能并在创建索引时手动处理,请将您Schema
的autoIndex
选项设置为false并在模型上使用ensureIndexes
方法。 -
capped
如果存在批量操作,该属性限制一次操作的量,capped如果要传递其他选项(如max或autoIndexId),该选项也可能设置为对象。在这种情况下,您必须显式传递size所需的选项。
new Schema({..}, { capped: { size: 1024, max: 1000, autoIndexId: true } });
-
collection
mongoose 默认使用模型名称来生成集合名称,并复数化, 你可以手动设置你希望的集合名称。 -
_id
默认情况下会生成_id
字段并默认为此字段创建索引,如果您根本不想_id
添加到您的架构,则可以使用此选项禁用它。 -
id
默认创建一个虚拟的getter,是由_id字符串形式或ObjectIds下返回的其hexString,如果您不希望将idgetter添加到模式中,则可以在模式构建时禁用它传递此选项。 -
read
允许在模式级别设置查询#读取选项,为我们提供一种将默认ReadPreferences应用于从模型派生的所有查询的方法。 -
strict
strict选项(默认情况下启用)确保传递给我们的模型构造函数的值未被保存到数据库。 -
safe(默认true)
将通过所有操作传递给MongoDB,并指定是否应将错误返回给我们的回调以及调整写入行为 -
shardKey strict(默认true)
使用分片时需要设置 -
toObject
将mongoose文件转换成一个简单的javascript对象,此方法接受几个选项。默认情况下,我们可以在每个文档的基础上应用这些选项,而不是在这里声明这些选项并将其应用于所有这些模式文档。 -
toJSON
与toObject选项完全相同,但仅在toJSON调用了documents 方法时才适用。 -
versionKey
versionKey由Mongoose首次创建时,它是每个文档上设置的一个属性。此键值包含 文档的内部 版本。默认的值是__v,但是可以自定义,也可以删除,不要这样做,除非你知道你在做什么。