获取对象数组中的每个嵌套对象的虚拟属性?
所以我知道如何获得一个单一的虚拟属性,如在Mongoose文档中所述:
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; });
我知道我是否错过了这里的东西。
您需要为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] });
当然,你可以定义一个额外的模式,但是mongoose已经在为你做这个了。
它存储在
PersonSchema.path('arrayAttr').schema
所以你可以通过把它添加到这个模式来设置一个虚拟的
PersonSchema.path('arrayAttr').schema.virtual('full').get(function() { return this.attr1 + '.' + this.attr2 })
首先你应该写
this.some_attr
而不是some_attr
你不能访问this.attr,因为在arrayAttr。 所以你可以做例如:
this.arrayAttr[0].attr1 + "." + this.arrayAttr[0].attr2
这是不安全的,因为arrayAttr可以是空的
如果你想要一个来自所有数组元素的计算值,这里是一个例子:
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 += ep; }); 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' }
我最喜欢的解决scheme是直接引用嵌套架构。
PersonSchema.paths.arrayAttr.schema.virtual('full').get(function() { return this.attr1 + '.' + this.attr2; });
另外需要注意的是,缺省情况下,虚拟模式不会被mongoose模式返回。 因此,请确保在嵌套架构上设置string化属性。
var options = { virtuals: true }; PersonSchema.paths.arrayAttr.schema.set('toJSON', options);