Mongoose 'reversed' population,即根据子模式中定义的引用填充父对象
Mongoose 'reversed' population, i.e. populating a parent object based on the reference defined in child schema
借用优秀的example from scaryguy修改如下:
项目组架构:
var ProjectGroupSchema = new Schema({
projectGroupId : String,
title : String
});
项目架构:
var ProjectSchema = new Schema({
title : {type : String, default : '', required : true},
group : {type: String, ref: 'ProjectGroup' },
subscribers : [{type: String, ref: 'User' }]
});
用户架构:
var UserSchema = new Schema({
userId : {type: String, require: true},
firstName : {type: String, required: true},
lastName : {type: String, required: true},
});
然后我可以做如下人口:
project.findById(req.projectId})
.populate('subscribers')
.populate('group')
.exec(function(err, project){
console.log(project);
});
请注意,引用字段不是对象 ID。
在此示例中,项目架构具有对项目组和订阅者的引用字段,这使得上述填充成为可能。
如果我想获取一个 ProjectGroup 对象,其中包含该组下的所有项目,并且每个项目都包含其订阅者怎么办?
我会说我正在寻找 'reversed' 总体,即根据子架构中定义的引用填充父对象。
目前我使用async先查询ProjectGroup,然后根据projectGroupId查询项目。
谢谢!
您可以使用聚合函数来实现。首先按 "projectGroup" 对项目进行分组,然后填充结果。
project.aggregate([
{$group: {_id: "$group", projects: {$push: "$$ROOT"}}}
],
function(err,results) {
user.populate( results, { "path": "projects.subscribers" }, function(err,results) {
if (err)
console.log(err);
res.send(results);
});
});
如果你想得到一个ProjectGroup对象,里面包含了该组下的所有项目。您可以使用 Populate Virtuals。 (猫鼬版本 > 4.5.0)
在您的架构文件中创建一个虚拟架构。
ProjectGroupSchema.virtual('projects', {
ref: 'Project', // The model to use
localField: 'projectGroupId', // Your local field, like a `FOREIGN KEY` in RDS
foreignField: 'group', // Your foreign field which `localField` linked to. Like `REFERENCES` in RDS
// If `justOne` is true, 'members' will be a single doc as opposed to
// an array. `justOne` is false by default.
justOne: false
});
查询如下:
ProjectGroup.find().populate('projects').exec(function(error, results) {
/* `results.projects` is now an array of instances of `Project` */
});
如果您看不到虚拟部分,请将 { toJSON: { virtuals: true } }
设置为您的模型。
var ProjectGroupSchema = new Schema({
projectGroupId : String,
title : String
}, { toJSON: { virtuals: true } });
借用优秀的example from scaryguy修改如下:
项目组架构:
var ProjectGroupSchema = new Schema({
projectGroupId : String,
title : String
});
项目架构:
var ProjectSchema = new Schema({
title : {type : String, default : '', required : true},
group : {type: String, ref: 'ProjectGroup' },
subscribers : [{type: String, ref: 'User' }]
});
用户架构:
var UserSchema = new Schema({
userId : {type: String, require: true},
firstName : {type: String, required: true},
lastName : {type: String, required: true},
});
然后我可以做如下人口:
project.findById(req.projectId})
.populate('subscribers')
.populate('group')
.exec(function(err, project){
console.log(project);
});
请注意,引用字段不是对象 ID。
在此示例中,项目架构具有对项目组和订阅者的引用字段,这使得上述填充成为可能。
如果我想获取一个 ProjectGroup 对象,其中包含该组下的所有项目,并且每个项目都包含其订阅者怎么办?
我会说我正在寻找 'reversed' 总体,即根据子架构中定义的引用填充父对象。 目前我使用async先查询ProjectGroup,然后根据projectGroupId查询项目。
谢谢!
您可以使用聚合函数来实现。首先按 "projectGroup" 对项目进行分组,然后填充结果。
project.aggregate([
{$group: {_id: "$group", projects: {$push: "$$ROOT"}}}
],
function(err,results) {
user.populate( results, { "path": "projects.subscribers" }, function(err,results) {
if (err)
console.log(err);
res.send(results);
});
});
如果你想得到一个ProjectGroup对象,里面包含了该组下的所有项目。您可以使用 Populate Virtuals。 (猫鼬版本 > 4.5.0)
在您的架构文件中创建一个虚拟架构。
ProjectGroupSchema.virtual('projects', {
ref: 'Project', // The model to use
localField: 'projectGroupId', // Your local field, like a `FOREIGN KEY` in RDS
foreignField: 'group', // Your foreign field which `localField` linked to. Like `REFERENCES` in RDS
// If `justOne` is true, 'members' will be a single doc as opposed to
// an array. `justOne` is false by default.
justOne: false
});
查询如下:
ProjectGroup.find().populate('projects').exec(function(error, results) {
/* `results.projects` is now an array of instances of `Project` */
});
如果您看不到虚拟部分,请将 { toJSON: { virtuals: true } }
设置为您的模型。
var ProjectGroupSchema = new Schema({
projectGroupId : String,
title : String
}, { toJSON: { virtuals: true } });