所以我知道如何获得单个虚拟属性,如Mongoose docs中所述:
PersonSchema
.virtual('name.full')
.get(function () {
return this.name.first + ' ' + this.name.last;
});
但是如果我的架构是:
var PersonSchema = new Schema({
name: {
first: String
, last: String
},
arrayAttr: [{
attr1: String,
attr2: String
}]
})
我想在arrayAttr中为每个嵌套对象添加一个虚拟属性:
PersonSchema.virtual('arrayAttr.full').get(function(){
return attr1+'.'+attr2;
});
Lemme知道我在这里错过了什么。
答案 0 :(得分:23)
您需要为attrArray
的元素定义单独的架构,并将虚拟属性添加到该架构。
var AttrSchema = new Schema({
attr1: String,
attr2: String
});
AttrSchema.virtual('full').get(function() {
return this.attr1 + '.' + this.attr2;
});
var PersonSchema = new Schema({
name: {
first: String
, last: String
},
arrayAttr: [AttrSchema]
});
答案 1 :(得分:6)
当然,你可以定义一个额外的架构,但是mongoose已经为你做了这个。
存储在
PersonSchema.path('arrayAttr').schema
因此,您可以通过将虚拟添加到此架构来设置虚拟
PersonSchema.path('arrayAttr').schema.virtual('full').get(function() {
return this.attr1 + '.' + this.attr2
})
答案 2 :(得分:2)
如果您想要所有数组元素的计算值,请参见以下示例:
const schema = new Schema({
name: String,
points: [{
p: { type: Number, required: true },
reason: { type: String, required: true },
date: { type: Date, default: Date.now }
}]
});
schema.virtual('totalPoints').get(function () {
let total = 0;
this.points.forEach(function(e) {
total += e.p;
});
return total;
});
User.create({
name: 'a',
points: [{ p: 1, reason: 'good person' }]
})
User.findOne().then(function(u) {
console.log(u.toJSON({virtuals: true}));
});
返回:
{ _id: 596b727fd4249421ba4de474,
__v: 0,
points:
[ { p: 1,
reason: 'good person',
_id: 596b727fd4249421ba4de475,
date: 2017-07-16T14:04:47.634Z,
id: '596b727fd4249421ba4de475' } ],
totalPoints: 1,
id: '596b727fd4249421ba4de474' }
答案 3 :(得分:0)
首先你应该写
this.some_attr
代替some_attr
你无法访问this.attr,因为arrayAttr中有。所以你可以这样做:
this.arrayAttr[0].attr1 + "." + this.arrayAttr[0].attr2
这不安全,因为arrayAttr可以为空
答案 4 :(得分:-1)
我最喜欢的解决方案是直接引用嵌套模式。
PersonSchema.paths.arrayAttr.schema.virtual('full').get(function() {
return this.attr1 + '.' + this.attr2;
});
值得注意的是,默认情况下,mongoose模式不会返回虚拟。因此,请确保在嵌套模式上设置字符串化属性。
var options = { virtuals: true };
PersonSchema.paths.arrayAttr.schema.set('toJSON', options);