---
# System prepended metadata

title: "\U0001F3C5 Day 6 - Mongoose、Schema"
tags: [Node.js 直播班 - 2024 春季班]

---

# 🏅 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)|
