# 🏅 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' });
```