13

所以我知道如何获取单个虚拟属性,如猫鼬文档中所述:

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;
});

让我知道我是否在这里错过了什么。

4

5 回答 5

25

您需要为元素定义一个单独的模式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]
});
于 2012-11-29T18:15:37.430 回答
7

当然,你可以定义一个额外的模式,但是 mongoose 已经为你做了这个。

它存储在

PersonSchema.path('arrayAttr').schema

因此,您可以通过将其添加到此架构来设置虚拟

PersonSchema.path('arrayAttr').schema.virtual('full').get(function() {
  return this.attr1 + '.' + this.attr2
})
于 2015-12-14T09:32:59.823 回答
4

如果您想从所有数组元素中计算出值,这里有一个示例:

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' }
于 2017-07-16T14:12:58.937 回答
0

首先你应该写

this.some_attr代替some_attr

而且您无法访问 this.attr,因为在 arrayAttr 中有。所以你可以做例如:

this.arrayAttr[0].attr1 + "." + this.arrayAttr[0].attr2

这是不安全的,因为 arrayAttr 可以为空

于 2012-11-29T17:51:40.527 回答
-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);
于 2017-05-25T15:09:44.443 回答