簡單的創建聲明三張表:user/department/project
const UserSchema = new mongoose.Schema({
username: { type: String, required: true },
password: { type: String, required: true },
department: { type: mongoose.Schema.Types.ObjectId, ref: 'Department'}
project: { type: mongoose.Schema.Types.ObjectId, ref: 'Project'}
})
const DepartmentSchema = new mongoose.Schema({
name: { type: String, required: true },
project: { type: mongoose.Schema.Types.ObjectId, ref: 'Project'}
})
const ProjectSchema = new mongoose.Schema({
name: { type: String, required: true },
owner: { type: mongoose.Schema.Types.ObjectId, ref: 'User'}
})
請忽略開發語言0_0…
- 查詢user表,以及關聯查詢project和department。深度爲1的多個關聯查詢用數組,單個用字符串即可。
model.User.find().populate(['department','project'])
- 查詢user表,關聯查詢project並且再查詢owner字段,即深度爲2的關聯查詢。
model.User.find().populate({ path: 'project', populate: { path: 'owner' } })
- 在2的基礎上查詢owner的時候只想要name字段,而password不返回。
model.User.find().populate({ path: 'project', populate: { path: 'owner', select: 'name' } })
- 1和2結合一起,即需要關聯查詢project和department,且project中再關聯查詢owner字段
const pop = [
{
path: 'department'
},
{
path: 'project',
populate: { path: 'owner' }
},
];
model.User.find().populate(pop);
另外有幾點需要注意:
- 如果關聯的字段是數組的話,跟上面用法是一樣的。
- 如果關聯字段查詢不到的話,比如上面
user.project = null
,如果是數組字段則爲空數組。 - 關聯的字段類型可以是
ObjectId, Number, String, and Buffer
,但是官方文檔上說:However, you should use ObjectId unless you are an advanced user and have a good reason for doing so.
下面說一下跟$lookup的關係
- user表中查到department可以用
populate
,也可以用$lookup
。但如果想在department表中查到user則只能用$lookup
。也就是說正向關聯的話兩者都能用,反向的話只能用$lookup
(但個人覺得正向的話還都是用populate
,因爲$lookup
寫法較麻煩)。 populate
用的是refs查詢,在性能上$lookup
比較有優勢,比如查詢user表一次出來10條記錄,再用refs查詢project需要10次,而$lookup
只需要1次。當然查詢次數固然會影響整個查詢過程消耗的時間,但相比在網絡中傳輸數據所耗費的時間還是可以接受的。- 簡單給出
$lookup
的用法。
在department中查詢到該部門下所有的user在department中查詢到該部門下所有的user在department中查詢到該部門下所有的user在department中查詢到該部門下所有的user
model.Department.aggregate([
{
$lookup: {
from: 'users', // 從哪個Schema中查詢(一般需要複數,除非聲明Schema的時候專門有處理)
localField: '_id', // 本地關聯的字段
foreignField: 'department', // user中用的關聯字段
as: 'users' // 查詢到所有user後放入的字段名,這個是自定義的,是個數組類型。
}
}
]);
更加詳細的內容參考populate的官方文檔