---
tags: Node.js 直播班 - 2023 春季班
---
# 第四週:期中考:打造全端 (FULL STACK) 網站架構
1. 錄影
4. [Adobe XD 設計稿](https://xd.adobe.com/view/c0763dbe-fc15-42e8-be0b-8956ed03e675-9525/grid)
6. [populate 圖表講解](https://whimsical.com/3CkqgyD3n3GvsCrdkywruw@2Ux7TurymMrP3RNMAaFD)
7. [第三堂直播程式碼](https://github.com/gonsakon/express-week3-sample)
## mongoDB 兩種資料設計方式
1. embedded:嵌入
2. references:引用
## embedded 嵌入作法
### room collection
``` =JSON
{
"_id":"6268b81991f46a33636be563",
"roomName":"標準單人房",
"users":[
{"name":"洧杰","age":28},
{"name":"Ray","age":29}
]
}
```
## references 引用作法
### room collection
``` =JSON
{
"_id":ObjectId("6268b90091f46a33636be58f"),
"roomName":"標準單人房",
"users": [
"6268b89591f46a33636be56a",
"6268b8b591f46a33636be56b"
]
}
```
### user collection
``` =JSON
[
{
"_id": ObjectId("6268b89591f46a33636be56a"),
"name":"洧杰",
"age":28
},
{
"_id": ObjectId("6268b8b591f46a33636be56b"),
"name":"Ray",
"age":29
}
]
```
### 引用語法
``` =JavaScript
db.rooms.aggregate( [{
$lookup: {
from: 'users',
localField: 'users',
foreignField: '_id',
as: 'users'
}
}])
```
## user collections
```
[
{
"name" : "John",
"email": "yy342@gmail.com",
"photo": "https://thumb.fakeface.rest/thumb_male_10_8c02e4e9bdc0e103530691acfca605f18caf1766.jpg"
},
{
"name" : "Mary",
"email": "mary0512@gmail.com",
"photo": "https://thumb.fakeface.rest/thumb_female_30_8ab46617938c195cadf80bc11a96ce906a47c110.jpg"
},
{
"name" : "Ada",
"email": "AdaWang@gmail.com",
"photo": "https://thumb.fakeface.rest/thumb_female_27_5a94a297efb15caf0e3d769ce1694953e8bf33e2.jpg"
}
]
```
## user model
:::spoiler schema
``` =javascript
const mongoose = require('mongoose');
const userSchema = new mongoose.Schema({
name: {
type: String,
required: [true, '請輸入您的名字']
},
email: {
type: String,
required: [true, '請輸入您的 Email'],
unique: true,
lowercase: true,
select: false
},
photo: String,
});
const User = mongoose.model('user', userSchema);
module.exports = User;
```
:::
## 貼文關鍵字搜尋與篩選
``` =JavaScript
const timeSort = req.query.timeSort == "asc" ? "createdAt":"-createdAt"
const q = req.query.q !== undefined ? {"content": new RegExp(req.query.q)} : {};
const post = await Post.find(q).populate({
path: 'user',
select: 'name photo '
}).sort(timeSort);
// asc 遞增(由小到大,由舊到新) createdAt ;
// desc 遞減(由大到小、由新到舊) "-createdAt"
```
## 本堂作業
- 設計[貼文](https://xd.adobe.com/view/c0763dbe-fc15-42e8-be0b-8956ed03e675-9525/screen/5b6bb2a0-f0f3-4b39-841f-8cf3a0ed9707)的 GET API,並需設計篩選功能(從新到舊貼文、從舊到最新、關鍵字搜尋)
- 設計[貼文](https://xd.adobe.com/view/c0763dbe-fc15-42e8-be0b-8956ed03e675-9525/screen/dfc7891e-63fd-4141-989a-8776ee7ea9f0) POST API,圖片先傳固定 url
> user 資料請先自行建立模擬資訊
![](https://i.imgur.com/rcPT5OS.png)