mongoose.Schema


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,也可以反解firstlast屬性

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

mongoose.Schema.options

有效的配置項

詳細使用根據鏈接查看官方文檔

  • autoIndex
    自動創建索引,在應用程序啟動時,Mongoose會ensureIndex為您聲明的每個索引發送一個命令Schema。在Mongoose v3中,background默認情況下會創建索引。如果要禁用自動創建功能并在創建索引時手動處理,請將您SchemaautoIndex選項設置為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,但是可以自定義,也可以刪除,不要這樣做,除非你知道你在做什么。
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容