如何使用动态引用填充Mongoose子文档的虚拟数组?

时间:2019-10-16 01:20:24

标签: mongoose

我可以在Mongoose的子文档数组中填充动态引用的虚拟字段(带有“ refPath”)吗?

数据结构类似于

Group
 - Members -> User

代码:模型/模式

let MemberSchema = new Schema({
  userId: {
    type: Schema.Types.ObjectId,
    refPath: 'userRef',
    required: true
  },
  userRef: {
    type: String,
    required: true,
    enum: ['Admin', 'User'],
    default: 'Admin'
  },
  isCreator: {
    type: Boolean,
    required: true,
    default: false
  },
  isManager: {
    type: Boolean,
    required: true,
    default: false
  },
  alias: {
    type: String,
    required: true
  },
  joined: {
    type: Number,
    required: true,
    default: UTIL.getTimestamp()
  }
}, {
  toObject: {
    virtuals: true
  },
  toJSON: {
    virtuals: true
  }
})

MemberSchema.virtual('user', {
  ref: (doc: IMember) => doc.userRef,
  localField: 'userId',
  foreignField: '_id',
  justOne: true
})

let GroupSchema = new Schema({
  title: {
    type: String,
    required: true
  },
  slug: {
    type: String,
    required: true,
    default: randomstring.generate({
      length: CONFIG.GROUP_NAME_LENGTH,
      charset: CONFIG.GROUP_NAME_CHARSET
    })
  },
  updated: {
    type: Number,
    required: true,
    default: UTIL.getTimestamp()
  },
  members: [MemberSchema]
}, {
  toObject: {
    virtuals: true
  },
  toJSON: {
    virtuals: true
  }
})

export default model('Group', GroupSchema)

代码:控制器

export function get(req, res) {
  GroupModel
  .findOne({
    slug: req.params.slug
  })
  .populate({
    path: 'members.user'
  })
  .exec()
  .then((data) => {
    if (data) {
      res.status(200).json(data)        
    } else {
      res.status(404).send()
    }
  })
  .catch((err) => {
    res.status(res.statusCode).send()
    console.log(err)
  })
}

如果在填充选项中添加{model:'Admin'},我将获得一个填充用户,但这完全违背了这个目的。

请帮助,我已经处理了将近24个小时。

1 个答案:

答案 0 :(得分:0)

我建议您将userId更改为user,而不是使用虚拟方法,并通过将refPathuserRef更改为members.userRef来填充它:

let MemberSchema = new Schema({
  user: {
    type: Schema.Types.ObjectId,
    refPath: 'members.userRef',
    required: true
  },
  userRef: {
    type: String,
    required: true,
    enum: ['Admin', 'User'],
    default: 'Admin'
  },
...
})
...

////// Controller:

GroupModel
  .findOne({
    slug: req.params.slug
  })
  .populate({
    path: 'members.user'
  })