为了在 MongoDB 中处理关系数据,您必须利用 DBrefs 功能。
我直接从我的一个生产项目中拿这些例子。
架构被严重截断,但仍讲述了 DBrefs 功能的故事。
它由两个模式组成:活动和用户
活动架构在这里:
/*eslint-env node*/
//Dependencies
const mongoose = require('mongoose');
//Global Constant
const Schema = mongoose.Schema;
// Create Schema
const ActivitySchema = new Schema({
activity: {
type: String,
},
description: {
type: String,
},
intensity: {
type: String,
},
hostId: {
type: Schema.Types.ObjectId,
ref: 'user'
},
}, {
collection: 'Activity'
});
mongoose.model('activity', ActivitySchema);
用户架构在这里:
/*eslint-env node*/
//Dependencies
const mongoose = require('mongoose');
//Global Constant
const Schema = mongoose.Schema;
//Create Schema
const UserSchema = new Schema({
name: {
type: String,
},
nickName: {
type: String
},
email: {
type: String,
},
password: {
type: String,
},
profImage: {
type: String,
},
interests: {
type: Array,
},
}, {
collection: 'User'
});
mongoose.model('user', UserSchema);
如您所见,在活动架构的末尾有一个名为 hostId 的字段,其类型为 Schema.Types.ObjectId 和一个指向用户架构的 ref: 字段。
它本质上是通过将用户的ObjectId 存储在活动集合(在 SQL 中称为表)中来将两个文档虚拟链接在一起。
只有当且仅当查询函数(例如,.findOne() 与 .populate() 聚合运算符一起调用时,这两个文档才真正链接在一起。
例子:
//Syntax: database.collection.queryFunction
//Normal Query:
db.activity.findOne({activity:'stack overflow event`})
.then(activityData=>{
console.log(activityData);
//You will get something like this:
[
{
activity: 'stack overflow event',
description: 'It's all about SO',
intensity: 'Very chill',
hostId: ObjectId(5ea1e3c89dcab6c27d1eb891),
}
]
})
.catch(err=>console.log(err))
//When you use .populate()
db.activity.findOne({activity:'stack overflow event`})
.populate('user')
.then(activityData=>{
console.log(activityData);
//You will get something like this:
[
{
activity: 'stack overflow event',
description: 'It's all about SO',
intensity: 'Very chill',
//The hostId field will get populate with the user object
hostId: {
name: 'SO Test User',
nickName: 'soTest',
email: 'xxx@xxx.com',
....it continues
}
}
]
})
.catch(err=>console.log(err))