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,但是可以自定義,也可以刪除,不要這樣做,除非你知道你在做什么。