--- tags: Node.js 直播班 - 2022 春季班 --- # 🏅 Day 18 ## Mongoose - Populate Mongoose 有提供 `populate()` 方法,可以將其他 collection 的資料關聯到目前在操作的 collection 這裡引用官方文件中的範例 ```javascript const mongoose = require('mongoose'); const { Schema } = mongoose; const personSchema = Schema({ _id: Schema.Types.ObjectId, name: String, age: Number, stories: [{ type: Schema.Types.ObjectId, ref: 'Story' }] }); const storySchema = Schema({ author: { type: Schema.Types.ObjectId, ref: 'Person' }, title: String, fans: [{ type: Schema.Types.ObjectId, ref: 'Person' }] }); const Story = mongoose.model('Story', storySchema); const Person = mongoose.model('Person', personSchema); ``` 可以看到上方最後兩行有兩個 Model,分別是 Story 和 Person,兩者也都有連到各自的資料庫 collection personSchema 中的 `stories` 欄位關聯至 storySchema 的 `id` 欄位,storySchema 的 `author` 及 `fans` 欄位,其中 `ref` 選項是告訴 Mongoose 關聯資料時要使用哪個 Model 接下來取得資料時就可以使用 `populate()` 加入相關設定,就可以在取得資料時依據 Schema 的設定取得其他 collection 的資料 ```javascript Story. find(). populate({ path: 'fans', select: 'name' }) ``` 取得 Story 資料時,資料的 fans 欄位就會關聯至 Person collection,找出符合該 id 的 document,`select` 是指定要取出該 document 的哪些欄位,上方範例是取出 document 中的 `name` 欄位 取出多個欄位的寫法為 `select: 'name age'`,就會取出 document 中的 `name` 和 `age` 欄位 ### 參考資源 [Mongoose v6.3.1: Query Population](https://mongoosejs.com/docs/populate.html) ### 題目(將答案寫在 HackMD 並提交至回報區) 以下為書籍與作者的 collection,請填入對應答案,讓取出單筆書籍資料時,可以關聯至 author 的資料 ```javascript const mongoose = require('mongoose'); const authorSchema = new mongoose.Schema({ name: String, introduction: String }, { versionKey: false } ); const bookSchema = new mongoose.Schema({ author : { type: mongoose.Schema.ObjectId, ref: /*請填入答案*/ }, title: String }, { versionKey: false } ); const Author = mongoose.model('Author', authorSchema); const Book = mongoose.model('Book', bookSchema); ``` 取出所有 books 的資料,關聯 author 欄位並指定顯示 author 資料的 name 欄位 ```javascript Book.find({_id: id })/*請填入答案*/ ``` 可使用此[專案](https://github.com/dogwantfly/mongoose-populate)練習及測試是否可正確運作,流程為以下 - 新增一筆 author 資料 - 帶入 author id 新增一筆 book 資料 - 以 book id 取得指定的 book 資料,並有正確顯示出 author 的 name 取得單筆 book 資料範例 ```json { "status": "success", "data": { "book": [ { "_id": "62700cf6fe019820d43e5332", "author": { "_id": "62700a66e6922ea65f83054b", "name": "Mike" }, "title": "book title" } ] } } ``` 回報流程 --- 請同學依照下圖教學觀看解答、回報答案: ![](https://i.imgur.com/QtL8zEW.png) 回報格式:請在「回報區」貼上 CodePen 或 HackMD 連結回報答案 (為了統計人數,請同學依序加上「報數」) <!-- 解答 ```javascript // models/books.js const bookSchema = new mongoose.Schema({ author : { type: mongoose.Schema.ObjectId, ref: 'Author' }, title: String }, { versionKey: false } ); // models/books.js const book = await Book.find({_id: id }).populate({ path: 'author', select: 'name' }); ``` --> 回報區 --- | 報數 | 組別 / 名字 | codepen / hackMD / 其他回饋 | | ---- | -------------------- | -------------------------------------------------------------------------------- | | 1 | 第 2 組 / Jin | [hackMD](https://hackmd.io/Y8rTw1SLTZSa808J546jCw) | | 2 | 第 2 組 / Vic | [hackMD](https://hackmd.io/HP5kDolYTxq_x2esoI7s1w) | | 3 | 第 3 組 / HedgehogKU | [HackMD](https://hackmd.io/y9FvJuwfT1-yIxkMK6dVGQ) | | 4 | 第 4 組 / 苡安 | [HackMD](https://hackmd.io/w-dg5L9fTyufWgMqBWX25g) | | 5 | 第 4 組 / 小宥 | [HackMD](https://hackmd.io/sMrIUyg0T4ekUt-ybCo2pg) | | 6 | 第 14 組|East | [HackMD](https://hackmd.io/5kqM65PoQnCzBOf0x-bGWA) | | 7 | 第 3 組|hiYifang | [HackMD](https://hackmd.io/@gPeowpvtQX2Om6AmD-s3xw/ryrhdUASq) | | 8 | 第 4 組 / sihle | [HackMD](https://hackmd.io/@bugbug777/H1X_LPASc) | | 9 | 第 9 組 / 黃士桓 | [HackMD](https://hackmd.io/pVWe-M72TamIPP23vf7drg?view) | | 10 | 第 2 組 / joe.chang | [HackMD](https://hackmd.io/uaRTw9c0TgOrADyXMmGL0Q?view#53---Mongoose---Populate) | | 11 | 第 8 組 / Hank | [HackMD](https://hackmd.io/@hank-hsiao/SkyRAPRB5)| | 12 | 第13組 / KFC | [HackMD](https://hackmd.io/sjkrN8_hQFup0hrRyPuarg?view)| | 13 |第 9 組 / konstante | [HackMD](https://hackmd.io/QUVAxgzvRj-XyT0JfeFQYw)| | 14 |第 3 組 / Justin | [HackMD](https://hackmd.io/wbu7sUlXRDKw9Ms6xN-XSw)| | 15 |Naiky | [HackMD](https://hackmd.io/@UWBC7rrORiKaLSBg226mZg/SJpnxO1L9)| | 16 |第 5 組 / Nap | [HackMD](https://hackmd.io/@8x8YzkXNSzafUSO3LZTmUw/B1ISd2RS9)| | 17 |第 11 組 / Han Lai | [HackMD](https://hackmd.io/CES_DOI7RQ6HrL-AL2Cd3g?view)| | 18 |第 8 組 / Jordan Tseng | [HackMD](https://hackmd.io/sKos3JGcTfOzygwfc-aFGA)| | 19 | 第 2 組 / wendy.li | [HackMD](https://hackmd.io/Y8rTw1SLTZSa808J546jCw) | | 20 | 第 1 組 / Claire | [HackMD](https://hackmd.io/Gg25Z4ssQbaCoRoJ8rNG1A) | | 21 | 第 7 組 / 程翔 | [HackMD](https://hackmd.io/CtRBdytJSSGAoQnh7O6O2Q?both) | | 22 | 第 3 組 / Hobby | [HackMD](https://hackmd.io/@hobbyling/day18) | | 23 | nick6303 | [HackMD](https://hackmd.io/i2Y0ZtKfSo6F7fnrD5iPgg)| | 24 | 第 15 組 / Chiu | [HackMD](https://hackmd.io/FmDaXPwnQKmEaFOvDZEaHA?both)| | 25 | 第 2 組 / Rikkubook | [HackMD](https://hackmd.io/XTEuRb3eR-WF-p8pTor5kA)| | 26 | 第 11 組 / mandy | [HackMD](https://hackmd.io/hZQQn95jSsK7yUTgigq-RQ?view)| | 27 | 第 1 組 / Ed Huang | [HackMD](https://hackmd.io/-1VSXfiYTNqF25Aw4g7_NA?view)| | 28 | 第 2 組 / peter | [HackMD](https://hackmd.io/@peterchen1024/r1Fe1wII9)| | 29 | 第 12 組 / Jimmy | [HackMD](https://hackmd.io/ijMKFC4CRBuIMD4fKxySlg)| | 30 | 第 10 組 / Otis | [HackMD](https://hackmd.io/uU1B5NKNROWSJEpyg-vPbQ?view)| | 31 | 第 7 組 / jason06286 | [HackMD](https://hackmd.io/-IJ3ACYQR3mtcdlY3zQp8A)| | 32 | 第 3 組 / 小葉 | [HackMD](https://hackmd.io/@FyKv37KcRSWqAO_e336w8g/BJrFnPJDq)| | 33 | 第 10 組 / 橘子 | [HackMD](https://hackmd.io/dQV8T95mS7-O-ud59mfMWQ)| | 34 | 第 16 組 / 皓皓 | [HackMD](https://hackmd.io/@cutecat8110/SyfwzsiPq)| | 35 |yolala | [HackMD](https://hackmd.io/5G2CgvJJRCS_r-aRfi4Y9A?both)|