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