--- tags: Node.js 直播班 - 2023 春季班 --- # 🏅 Day 6 - Mongoose、Schema ### Mongoose Mongoose 是 MongoDB 的 ODM(Object Data Modeling)套件,Mongoose 套件會藉由 MongoDB driver 操作資料庫的資料 使用 ODM 通常可以降低開發和維護成本,因 ODM 會使用 JavaScript 的物件反映出資料庫中的資料,相對於使用資料庫原生的查詢語言 (SQL),用 ODM 的方式操作資料庫會更好上手 - 在專案中安裝 Mongoose ```javascript npm install mongoose --save ``` - 引入 mongoose 套件並連線 MongoDB 資料庫 ```javascript= const mongoose = require('mongoose'); mongoose.connect('mongodb://localhost:27017/test'); // test 為資料庫的名稱,可以改為自己的資料庫名稱 ``` ### Schema 安裝 Mongoose 並連線至資料庫後,接著可以開始建立 Schema(資料庫綱要),定義需要哪些資料、型別、是否顯示、預設值... 等等 例如:[文件](https://mongoosejs.com/docs/guide.html)中列出 Blog 的 Schema ```javascript= 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 ```javascript title: {type: String} // 代表 title 需為一個字串 ``` 若只有設定型別可以使用簡寫 `title: String` 若 title 是一個**物件**,可以針對裡面的屬性設定型別 ```javascript title: { chinese: {type: String}, english: {type: String} } ``` 若 title 為一個**陣列**,也可指定陣列中資料型別 ```javascript title: [{type: String}] // 若只有設定型別可以使用簡寫 [String] ``` #### required 若此資料需為必填項目,可以設定 required,並且可客製化錯誤訊息,格式如下: ```javascript title: { type: String, required: [true, 'title 為必填'] } ``` #### default 若有資料未填寫,也可以設定此資料的預設值 ```javascript title: { type: String, default: '未命名的文章' } ``` 通常 required 與 default 不會同時使用 #### select 若有資料欄位希望可以被保護,不顯示出來,可以加入 select 設定 例如:若有涉及使用者相關個資 password、email ... 等等,都會建議加入 `select: false` 不將資料回傳給前端 ```javascript password: { type: String, select: false } ``` #### enum 若此資料設定型別為 `String` 或 `Number`,可以設定 `enum` 指定需為哪些值 以字串為例,若 author 需為 Amy、Bob 或 Cody 其中之一,可以設定為以下: ```javascript author: { type: String, enum: ['Amy','Bob','Cody'] } ``` ### 參考資源 - [Mongoose v6.2.10: Schemas](https://mongoosejs.com/docs/guide.html) - [Mongoose v6.2.10: SchemaTypes](https://mongoosejs.com/docs/schematypes.html) - 課程影音「Mongoose NPM 教學」(可看到 Mongoose 新增 Model 流程) ## 題目 請參考以下需求,設計手搖飲的 Schema ``` - 產品名稱(product): 需為字串,必填,若未填寫,錯誤訊息為「產品名稱未填寫」 - 價錢(price): 需為數字, 必填,若未填寫,錯誤訊息為「價錢未填寫」 - 冰塊(ice): 需為字串, 若未填寫預設為 '正常冰' - 甜度(sugar):需為字串,若未填寫預設為 '全糖' - 配料(toppings):為陣列,內容需為字串 ``` ```javascript= const drinkSchema = new mongoose.Schema({ /* 請在此填入答案 */ }); ``` ## 回報流程 將答案寫在 CodePen 並複製 CodePen 連結貼至底下回報就算完成了喔! 解答位置請參考下圖(需打開程式碼的部分觀看) ![](https://i.imgur.com/vftL5i0.png) <!-- 解答: ```javascript const drinkSchema = new mongoose.Schema({ product: { type: String, required: [true, '產品名稱未填寫'] }, price: { type: Number, required: [true, '價錢未填寫'] }, ice: { type: String, default: "正常冰" }, sugar: { type: String, default: "全糖" }, toppings: [{type: String}] }); ``` --> 回報區 --- | 報數 | 組別/Discord 名字 | Codepen/其他回饋 | |:----:|:-------------------:|:---------------------------------------------------------------------------------------------------------------------------------:| | 1 | 北 10 組 / Benson | [Github Benson - Day 6](https://github.com/ioveasdkre/HexschoolOperation/tree/main/NodejsEnterpriseClass/day40-tasks/day6/app.ts) | | 2 | 北 1 組 / PittWu | [Blog Post - Day 6](https://pitt-wu-blog.vercel.app/docs/day6-mongoose-schema) | | 3 | 北 8 組 / Zhao Chen | [GitHub - Day 6](https://github.com/zhao1995chen/NodejsEnterpriseClass/blob/master/daily-task/day6/index.ts) | | 4 | 北 1 組 / MayYi | [HackMD - Day 6](https://hackmd.io/Yxa67cGPTEq_Dpqeil5uEA) | | 5 | 南 2 組 / fengyao | [GitHub - Day 6](https://github.com/fengyao33/sixfeet/blob/main/pratice6-schemas.ts) | | 6 | 中 3 組 / Wendy | [Notion - Day 6](https://jewel-cellar-80e.notion.site/Day-6-Mongoose-Schema-8af94acad5e84632999ee1436167fc03) | | 7 | 中 4 組 / jimkk159 | [codepen - Day 6](https://codepen.io/jimkk159/pen/bGxQqzM)| | 8 | 北 5 組 / 圈圈 | [codepen - Day 6](https://codepen.io/wjejfczn-the-bold/pen/zYJyEar)| | 9 | 北 12 組 / Sam Lin | [GitHub - Day 6](https://github.com/samlin1122/hex-school/blob/main/daily-challenges/day6.js) | 10 | 北 8 組 / Ryder | [Codepen - Day 6](https://codepen.io/rider159159/pen/MWqLrmO) | 11 | 北 13 組 / Louisa | [GitHub - Day 6](https://github.com/louisa0416/NodejsEnterpriseClass/tree/master/daily-task/day06) | | 12 | 北 13 組 / sasha | [Codepen - Day 6](https://codepen.io/sasay/pen/GRXbLZy)| | 13 | 北5組 / albee |[GitHub-Day 6](https://github.com/albee-chang/hexschool-node-dailytask/blob/main/day6/app.js)| | 14 | 南 1 組 / hiYifang |[CodePen-Day 6](https://codepen.io/hiYifang/pen/qBpLqWG)| | 15 | 北 16 組 / 啊培培 |[GitHub-Day 6](https://github.com/LABIBI-LG/Courses/blob/main/hexschool/nodeJS/Live_Course/Daily_Tasks/day6/main.js)|