# 🏅 Day 6 - Mongoose、Schema ### Mongoose Mongoose 是 MongoDB 的 ODM(Object Data Modeling)套件,Mongoose 套件會藉由 MongoDB driver 操作資料庫的資料。 使用 ODM 通常可以降低開發和維護成本,因 ODM 會使用 JavaScript 的物件反映出資料庫中的資料,相對於使用資料庫原生的查詢語言 (SQL),用 ODM 的方式操作資料庫會更好上手。 引入 Mongoose 並連線至 MongoDB 資料庫 > 使用前需先安裝 `npm install mongooose --save` ```javascript // 引入 mongoose const mongoose = require('mongoose'); // 連線至資料庫 mongoose.connect('mongodb://localhost:27017/database'); // `database` 為資料庫名稱,可替換成自定義的資料庫 ``` > 注意: > 若是連線時遇到 `MongooseServerSelectionError: connect ECONNREFUSED ::1:27017` 相關錯誤,可將 `localhost` 替換成 `127.0.0.1` > 詳細可參考:[Mongoose Connections](https://mongoosejs.com/docs/connections.html) ### Schema 綱要,定義該資料的規則:設定資料屬性、型別、是否必填、預設值 … 等等 當接收到資料,就可以依此 Schema 確認資料是否帶入正確 以訂房資訊的 Schema 為例: ```javascript const orderSchema = new mongoose.Schema({ user: { type: String, required: [true, 'user is required.'], }, userTel: { type: String, required: [true, 'userTel is required.'], select: false }, room: { type: String, required: [true, 'room is required.'], enum: ['單人房','雙人房','四人房'] }, isPaid: { type: Boolean, default: false }, createdAt: { type: Date, default: Date.now } }); ``` 以下介紹上方運用到的相關設定: #### type 設定資料的**型別**(Number、String、Boolean ...) `room: { type: String }` > 若是只有設定型別,可以簡寫為 `room: String` > 更多型別設定可觀看 [Mongoose: SchemaTypes](https://mongoosejs.com/docs/schematypes.html) #### required 設定資料是否**必填**與客製化錯誤訊息 ```javascript room: { type: String, required: [true, 'room is required.'] } ``` #### default 設定資料的**預設值**(通常 required 與 default 不會同時使用) ```javascript isPaid: { type: Boolean, default: false } ``` #### select 若有資料欄位希望可以被保護,不顯示出來,可以加入 select 設定 例如:若有涉及使用者相關個資 password、email ... 等等,都會建議加入 `select: false` 不將資料回傳給前端 ```javascript userTel: { type: String, select: false } ``` #### enum 若此資料設定型別為 `String` 或 `Number`,可以設定 `enum` 指定需為哪些值 以字串為例,若 room 需為 `單人房`、`雙人房` 或 `四人房` 其中之一,可以設定為以下: ```javascript room: { type: String, enum: ['單人房','雙人房','四人房'] } ``` ### 參考資源 - [Mongoose: Schemas](https://mongoosejs.com/docs/guide.html) - [Mongoose: SchemaTypes](https://mongoosejs.com/docs/schematypes.html) - 課程影音「Mongoose NPM 教學」 題目 --- 請參考以下需求,設計房間的 Schema - 房型(room): 需為字串、必填,若未填寫,錯誤訊息為「`房型為必填`」 - 定價(price): 需為數字、必填,若未填寫,錯誤訊息為「`定價為必填`」 - 最大容納人數(max):需為數字,需為「2、4、6」其中之一 - 是否含衛浴(bathroom):需為布林值,預設為 false - 房間備品(amenities):為陣列,陣列內容需為字串 ```javascript= const roomSchema = new mongoose.Schema({ /* 請在此填入答案 */ }); ``` ## 回報流程 將答案寫在 CodePen 並複製 CodePen 連結貼至底下回報就算完成了喔! 解答位置請參考下圖(需打開程式碼的部分觀看) ![](https://i.imgur.com/vftL5i0.png) <!-- 解答: const roomSchema = new mongoose.Schema({ room: { type: String, required: [true, '房型為必填'] }, price: { type: Number, required: [true, '定價為必填'] }, max: { type: Number, enum: [2, 4, 6], }, bathroom: { type: Boolean, default: false }, amenities: [{ type: String }] }); --> 回報區 --- <!-- 將答案貼至下方表格內,格式: | Discord 暱稱 | [CodePen](連結) | --> | Discord | CodePen / 答案 | |:-------------:|:-----------------:| | xxx | [CodePen]() | | 苡安 | [hackmd](https://hackmd.io/@L7K9-66lSeagS28AP0_GjQ/SkF68n4lR) | | 群嘉 | [CodePen](https://codepen.io/efzdamnp-the-lessful/pen/zYXaYZB?editors=0010)| | YC | [CodePen](https://codepen.io/YCLu/pen/XWQEzKp) | | ellallu0903 | [CodePen](https://codepen.io/ellallu0903/pen/eYoKmgG) | | shuantt | [CodePen](https://codepen.io/th-tseng/pen/jORKEBV)| | Lobinda | [CodePen](https://codepen.io/Lobinda/pen/dyLKPoq)| | Aida | [CodePen](https://codepen.io/ada23410/pen/wvZXBYz?editors=0010)| | Chia Pin | [CodePen](https://codepen.io/joker-cat/pen/QWPxbBB)| | 阿旭 | [CodePen](https://codepen.io/koei-lu/pen/OJGEVqQ?editors=1010)| | kelvinnn | [CodePen](https://codepen.io/is-lin/pen/GRLGRjd?editors=0010)| | Theodore | [CodePen](https://codepen.io/GustavoFringgg/pen/ExJRPbL?editors=0010) | | wei | [CodePen](https://codepen.io/Wei-the-sasster/pen/BaEVjPK?editors=0010) | | tung030374 | [CodePen](https://codepen.io/tung__u/pen/qBwKayL) | |cho|[CodePen](https://codepen.io/cho195/pen/eYoKdVy)| | Hank | [CodePen](https://codepen.io/tw1720/pen/WNWypyo) | | 羽 | [CodePen](https://codepen.io/lingling-Syu/pen/dyLKJBB?editors=0010) | | 圈圈 | [CodePen](https://codepen.io/wjejfczn-the-bold/pen/bGJKaXg) | | Jean | [CodePen](https://codepen.io/jeanchiang1221/pen/xxezYdo) | | Otis | [CodePen](https://codepen.io/humming74/pen/PogaeZv) | | Tiya | [CodePen](https://codepen.io/Tiya_blank/pen/JjVZaWv) | | yiling4054 | [CodePen](https://codepen.io/lin010/pen/abxKaeQ) | | ej_chuang | [CodePen](https://codepen.io/EJChuang/pen/abxKQPJ) | | william_hsu | [CodePen](https://codepen.io/william8815/pen/ZEZRmBz) | | Thomas | [CodePen](https://codepen.io/ThomasYeh/pen/qBwyBKm) | | william威良 | [CodePen](https://codepen.io/snowman12320/pen/LYvBVPa?editors=1010) | | runweiting | [CodePen](https://codepen.io/weiting14/pen/xxeJVdB) | | Fabio20 | [CodePen](https://codepen.io/fabio7621/pen/LYvBZqj) | | mei | [Codepen](https://codepen.io/l_umei/pen/mdgjmYR)| | jenny7532 | [Codepen](https://codepen.io/wei-chen-wu/pen/abxjQoe)| | 2魚 | [Codepen](https://codepen.io/ijrekmsn-the-sans/pen/RwOBvNX) | | Henry | [Codepen](https://codepen.io/hekman1122/pen/eYojqgd?editors=0010) | | Benson | [Codepen](https://codepen.io/nosneb83/pen/BaEOpwY) | | zaoannihao | [CodePen](https://codepen.io/ckhwdvrx-the-solid/pen/jORvwJJ) | | 瑀君 | [Codepen](https://codepen.io/yennnnn/pen/QWPVOxZ)| | blp100x | [Codepen](https://codepen.io/blp100/pen/PogdvxN)| | yoshidc | [CodePen](https://codepen.io/yoshiyyc/pen/VwNVVXw)| | Ciel | [CodePen](https://codepen.io/nycteachen/pen/vYMQPRO)| | albertyang3576 | [CodePen](https://codepen.io/albertyang3576/pen/ZEZZOVe?editors=0010)| | puffy_chen | [CodenPen](https://codepen.io/TernMayDay/pen/XWwmoBo)|