NestJS嵌套对象Schema配置问题:GraphQL @Field装饰器异常解决
问题解决:NestJS中MongoDB嵌套对象结合GraphQL的字段处理
问题背景
MongoDB模型结构:
{ ... settings: { positions: [ { column: number, row: number, buttonId: (ref to Button model) } ] } }
用户原NestJS Schema定义:
@Schema({ _id: false }) @ObjectType() class Settings { @Field(() => [Object]) @Prop({ type: [{ column: Number, row: Number, buttonId: String }] }) positions: { column: number; row: number; buttonId: string }; } const SettingsSchema = SchemaFactory.createForClass(Settings); @Schema() @ObjectType() export class Keyboard { @Field(() => ID) _id: string; @Field(() => User) @Prop({ type: mongoose.Schema.Types.ObjectId, ref: 'User' }) author: User; @Field(() => Group, { nullable: true }) @Prop({ type: mongoose.Schema.Types.ObjectId, ref: 'Group' }) group?: Group; @Field(() => Settings, { nullable: true }) @Prop({ type: SettingsSchema }) settings?: Settings; } export const KeyboardSchema = SchemaFactory.createForClass(Keyboard);
出现的错误:
Cannot determine GraphQL output type for 'positions' of 'Settings' class. Make sure your class is decorated with an appropriate decorator.
解决方案
问题核心是Settings类的positions字段用了[Object]作为GraphQL类型,GraphQL无法识别匿名对象结构。需为数组内的子对象单独定义类型:
- 定义
Position子对象的Schema和GraphQL类型
import { Schema, Prop, SchemaFactory } from '@nestjs/mongoose'; import { ObjectType, Field, ID } from '@nestjs/graphql'; @Schema({ _id: false }) @ObjectType() class Position { @Field(() => Number) @Prop({ type: Number, required: true }) column: number; @Field(() => Number) @Prop({ type: Number, required: true }) row: number; @Field(() => ID) @Prop({ type: Schema.Types.ObjectId, ref: 'Button', required: true }) buttonId: string; } const PositionSchema = SchemaFactory.createForClass(Position);
- 修改
Settings类,使用明确的Position类型
@Schema({ _id: false }) @ObjectType() class Settings { @Field(() => [Position]) @Prop({ type: [PositionSchema], default: [] }) positions: Position[]; } const SettingsSchema = SchemaFactory.createForClass(Settings);
Keyboard类保持原有定义即可
@Schema() @ObjectType() export class Keyboard { @Field(() => ID) _id: string; @Field(() => User) @Prop({ type: mongoose.Schema.Types.ObjectId, ref: 'User' }) author: User; @Field(() => Group, { nullable: true }) @Prop({ type: mongoose.Schema.Types.ObjectId, ref: 'Group' }) group?: Group; @Field(() => Settings, { nullable: true }) @Prop({ type: SettingsSchema }) settings?: Settings; } export const KeyboardSchema = SchemaFactory.createForClass(Keyboard);
关键说明
- GraphQL要求明确的类型定义,不能用匿名
Object作为字段类型,必须为每个嵌套对象添加@ObjectType()装饰器 - Mongoose嵌套数组字段直接引用子对象Schema即可,SchemaFactory会自动处理结构映射
- 若
buttonId是Button模型的引用,需在Prop中指定ref: 'Button',同时GraphQL字段用ID类型对应
内容的提问来源于stack exchange,提问作者LastJonOff
相关产品推荐
相关产品推荐

