Mongoose嵌套对象数组schema中字段getter未生效问题求助
问题根因
Mongoose 中嵌套在数组内的隐式子文档不会继承父 Schema 的 toObject/toJSON 配置,你仅在根级 SectionSchema 开启了 getter 生效配置,嵌套的 allowedUsers 子字段所属的隐式子 Schema 没有对应配置,因此字段的 getter 不会被触发。
可行解决方案
方案1:显式定义嵌套子Schema并开启getter(最符合Mongoose规范)
将allowedUsers的结构抽为独立子Schema,单独配置getter生效规则:
const mongoose = require('mongoose'); const mongooseUniqueValidator = require('mongoose-unique-validator'); const mongooseTimestamp = require('mongoose-timestamp'); const Schema = mongoose.Schema; // 抽离allowedUsers的子Schema,单独配置getter生效 const AllowedUserSchema = new Schema({ user: {type: Schema.Types.ObjectId}, actions: {type: 'String', get: toObject}, _id: false }, { toObject: { getters: true }, toJSON: { getters: true } }) const SectionSchema = new Schema({ name: {type: 'String', required: true}, system: {type: Schema.Types.ObjectId, required: true, ref: 'System'}, subsystem: {type: Schema.Types.ObjectId, required: true, ref: 'Subsystem'}, createdBy: {type: Schema.Types.ObjectId, required: true, ref: 'User'}, allowedUsers: [AllowedUserSchema], // 替换原来的内联结构 }, {versionKey: 'versionKey'}); SectionSchema.plugin(mongooseTimestamp); SectionSchema.plugin(mongooseUniqueValidator); function toObject (v) { return v ? JSON.parse(v) : v; // 加空值判断避免解析空值时报错 } SectionSchema.set('toObject', { getters: true }); SectionSchema.set('toJSON', { getters: true }); module.exports = mongoose.model('Section', SectionSchema);
方案2:查询结果后手动转换(改动最小)
如果不想调整Schema结构,直接在查询返回结果后手动处理actions字段即可:
// exec回调的resolve逻辑修改如下 } else { // 遍历转换actions字段 const processedSections = sections.map(section => { const sectionObj = section.toObject(); sectionObj.allowedUsers = sectionObj.allowedUsers.map(item => { item.actions = JSON.parse(item.actions); return item; }) return sectionObj; }) resolve({ data: processedSections, filterParameters: filterParameters }); }
方案3:直接使用Schema的Mixed类型存储JSON(从根源避免转换问题)
如果业务允许,直接将actions字段类型设为Schema.Types.Mixed,Mongoose会自动存储/读取JSON对象,不需要手动写getter转换:
allowedUsers: [{ user: {type: Schema.Types.ObjectId}, actions: {type: Schema.Types.Mixed}, // 直接存对象,无需额外转换 _id: false }],
内容的提问来源于stack exchange,提问作者Emad
相关产品推荐
相关产品推荐

