我试图在我的一个模式中创建一个虚拟项目,需要访问此模式中引用的项目所引用的数据(是,这2个引用深入,连接3个模式/模型)
我尝试使用Model / Schema A / B / C尽可能接近地模拟代码。
这将是 ModelA 的架构,其中包含取决于引用的虚拟项目:
// models/modela.js
// SchemaA for ModelA
const SchemaA = new Schema({
_foo: {
// References ModelB
type: Schema.Types.ObjectId,
ref: 'ModelB'
}
})
// Virtual `Modela.something`, which needs the data from ModelC.baz
SchemaA.virtual('something').get(function () {
// How can I access ModelC.baz
return 'Value from ModelC'
});
然后是 ModelB 的架构:
// models/modelb.js
// SchemaB for ModelB
const SchemaB = new Schema({
_bar: [{
// References ModelC.baz
type: Schema.Types.ObjectId,
ref: 'ModelC'
}]
})
ModelC 的架构:
// models/modelc.js
// SchemaC for ModelC
const SchemaC = new Schema({
baz: Schema.Types.String
})
如您所见,我需要做的是从 ModelA
中的虚拟something
项目中访问 Modelc.haz
我认为如果我通过查询本身做了两个人群,那么也许这会有用,所以我尝试了类似的东西:
this.find()
.populate( '_foo' )
.populate( '_foo._bar' )
哪个不起作用(我实际上并没有真正期待它,但是很好)
答案 0 :(得分:1)
您可以使用Model.populate方法来实现此目的:
ModelA
.find()
.populate({
path: '_foo'
})
.exec(function(err, docs) {
if (err) throw err;
// Populate the '_bar' array of the '_foo' property which is
// an instance of ModelB
ModelB.populate(docs[0]._foo, { path: '_bar' }, function(err, result) {
console.log('Showing ModelC.baz:', docs[0].something);
});
});
您可以像这样定义虚拟属性:
SchemaA.virtual('something').get(function () {
// How can I access ModelC.baz
return this._foo._bar[0].baz;
});
答案 1 :(得分:0)
您可以在this github issue找到有关此内容的更多信息。您可以使用查询挂钩。
我有类似的问题,所以我用它来填充参考模型以用于虚拟功能。这是一个样本。
const tutorialSchema = new mongoose.Schema({
title: {
type: String,
required: true
},
videos: [
{
type: mongoose.Schema.Types.ObjectId,
ref: 'Video'
}
]
});
tutorialSchema.pre('findOne', function (next) {
this.populate('videos'); // now can be accessed using this.videos
next();
});
tutorialSchema.virtual('totalTime').get(function () {
let times = [];
times = this.videos.map((v) => {
return v.duration;
});
if(times.length === 0) return 0;
let totalTime; // find total time of videos and then return
return totalTime;
});