---
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 連結貼至底下回報就算完成了喔!
解答位置請參考下圖(需打開程式碼的部分觀看)

<!-- 解答:
```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)|