觀念解說 – Mongoose、schema
Mongoose
Mongoose 是 MongoDB 的 ODM(Object Data Modeling) 套件,Mongoose 套件會藉由 MongoDB driver 操作資料庫的資料
使用 ODM 通常可以降低開發和維護成本,因 ODM 會使用 JavaScript 的物件反映出資料庫中的資料,相對於使用資料庫原生的查詢語言 (SQL),用 ODM 的方式操作資料庫會更好上手
- 在專案中安裝 Mongoose1npm install mongoose --save
 -  引入 mongoose 套件並連線 MongoDB 資料庫123const mongoose = require('mongoose');mongoose.connect('mongodb://localhost:27017/test');// test 為資料庫的名稱,可以改為自己的資料庫名稱
 
Schema
安裝 Mongoose 並連線至資料庫後,接著可以開始建立 Schema(資料庫綱要),定義需要哪些資料、型別、是否顯示、預設值…等等
例如:文件中列出 Blog 的 Schema
1 2 3 4 5 6 7 8 9 10 11 12  | const blogSchema = new mongoose.Schema({   title:  String, // String is shorthand for {type: 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 中會有需要帶入的資料屬性,title、author 等等,並會針對此資料加入相關設定,例如:型別、必填、預設…等等
type
1  | title: {type: String} // 代表 title 需為一個字串  | 
若只有設定型別可以使用簡寫 title: String
若 title 是一個物件,可以針對裡面的屬性設定型別
1 2 3 4  | title: {   chinese: {type: String},   english: {type: String} }  | 
若 title 為一個陣列,也可指定陣列中資料型別
1  | title: [{type: String}] // 若只有設定型別可以使用簡寫 [String]  | 
required
若此資料需為必填項目,可以設定 required,並且可客製化錯誤訊息,格式如下:
1 2 3 4  | title: {   type: String,   required: [true, 'title 為必填'] }  | 
default
若有資料未填寫,也可以設定此資料的預設值
1 2 3 4  | title: {   type: String,   default: '未命名的文章' }  | 
通常 required 與 default 不會同時使用
select
若有資料欄位希望可以被保護,不顯示出來,可以加入 select 設定
 例如:若有涉及使用者相關個資 password、email …等等,都會建議加入 select: false 不將資料回傳給前端
1 2 3 4  | password: {   type: String,   select: false }  | 
enum
若此資料設定型別為 String 或 Number,可以設定 enum 指定需為哪些值
 以字串為例,若 author 需為 Amy、Bob 或 Cody 其中之一,可以設定為以下:
1 2 3 4  | author: {   type: String,   enum: ['Amy','Bob','Cody'] }  | 
參考資源
– Mongoose v6.2.10: Schemas
 – Mongoose v6.2.10: SchemaTypes
 – Mongoose NPM 教學(可看到 Mongoose 新增 Model 流程)(章節影片)
解題
題目(將答案寫在 CodePen 並提交至回報區)
請參考以下需求,設計手搖飲的 Schema
1 2 3 4 5  | - 產品名稱(product): 需為字串,必填,若未填寫,錯誤訊息為「產品名稱未填寫」 - 價錢(price): 需為數字, 必填,若未填寫,錯誤訊息為「價錢未填寫」 - 冰塊(ice): 需為字串, 若未填寫預設為 '正常冰' - 甜度(sugar):需為字串,若未填寫預設為 '全糖' - 配料(toppings):為陣列,內容需為字串  | 
1 2 3  | const drinkSchema = new mongoose.Schema({    /* 請在此填入答案 */ });  | 
解答與完整程式碼
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21  | const drinkSchema = new mongoose.Schema({   product: {     type: String,     required: [true, '產品名稱未填寫'],   },   price: {     type: Number,     required: [true, '價錢未填寫'],   },   ice: {     type: String,     default: '正常冰',     enum: ['去冰', '微冰', '少冰', '正常冰', '多冰'],   },   sugar: {     type: String,     default: '全糖',     enum: ['無糖', '微糖', '半糖', '少糖', '全糖'],   },   toppings: [{ type: String }], });  | 
