# 🏅 Day 18 - Mongoose - Populate Mongoose 有提供 `populate()` 方法並搭配在 schema 設定 ref 關聯,就可以將其他 collection 的資料關聯到目前在操作的 collection 以作業設計稿貼文為例,貼文除了貼文內容、圖片、貼文建立時間,也會需要使用者的資料來記錄該則貼文是哪位使用者發布的 舉例: ```javascript= const mongoose = require('mongoose'); // 使用者 Schema、Model const userSchema = new mongoose.Schema({ name: { type: String, required: [true, '名字未填寫'] }, email: { type: String, required: [true, 'Email 未填寫'], select: false }, photo: { type: String, default: '' } }, { versionKey: false }); const User = mongoose.model('User', userSchema); // 貼文 Schema、Model const postSchema = new mongoose.Schema({ user: { type: mongoose.Schema.ObjectId, // users collection 的 _id ref: 'User' // 使用者的 Model 名稱 }, content: { type: String, required: [true, '貼文內容未填寫'] }, image: { type: String, default: '' }, createdAt: { type: Date, default: Date.now }, likes: { type: Number, default: '' } }, { versionKey: false }); const Post = mongoose.model('Post', postSchema); ``` > Post 要關聯到 User 需在 schema 的 `user` 欄位設定 `ref` 告訴 Mongoose 關聯資料時要使用哪個 Model 接下來就可以使用 `populate()` 加入相關設定,就可以在取得 Post 資料時依據 Schema 的設定取得 User 的 collection 資料 大致如下: ```javascript= Post.find() .populate({ path: 'user', select: 'name' }) ``` 取得 Post 資料時: - `path` 設定為有關聯到 User 的屬性 `user`,就會關聯到 User 的 collection 並找出符合該 id 的資料 - `select` 可以指定要取出該資料的哪個欄位,以上方範例來說就會取出 `name` 欄位。 使用空格間隔可以取出多個欄位,像是:`select: 'name photo'`,就會取出 `name` 和 `photo` 欄位 ### 參考資源 - [Mongoose: Query Population](https://mongoosejs.com/docs/populate.html) - [Mongoose: Schema ref](https://mongoosejs.com/docs/api/schematype.html#SchemaType.prototype.ref()) 題目(回報作業) --- 延續上方範例,貼文下方的按讚 `likes` 通常會需要知道是哪位使用者按讚的,請嘗試調整貼文的 Schema,讓 `likes` 關聯使用者,當取出貼文資料時可以關聯使用者,並取出使用者的名字與圖片資料 完整下方程式碼(補上 `...` 的部分) ```javascript= const mongoose = require('mongoose'); // 使用者 Schema、Model const userSchema = new mongoose.Schema({ name: { type: String, required: [true, '名字未填寫'] }, email: { type: String, required: [true, 'Email 未填寫'], select: false }, photo: { type: String, default: '' } }, { versionKey: false }); const User = mongoose.model('User', userSchema); // 貼文 Schema、Model const postSchema = new mongoose.Schema({ user: { type: mongoose.Schema.ObjectId, ref: 'User' }, content: { type: String, required: [true, '貼文內容未填寫'] }, image: { type: String, default: '' }, createdAt: { type: Date, default: Date.now }, likes: [{ type: mongoose.Schema.ObjectId, ref: 'User' }], }, { versionKey: false }); const Post = mongoose.model('Post', postSchema); // 取得貼文資料 Post.find() .populate({ path: 'user', select: 'name photo' }); ```