You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Mongoose嵌套对象中子文档引用异常:存完整对象而非ObjectId

问题解决:Mongoose嵌套对象中的引用字段异常

你遇到的问题是嵌套在metadata对象里的roles字段没有正确处理集合引用——既不存储ObjectId反而保存完整对象,创建文档时也不会生成默认空数组,但外层的同类型字段却能正常工作。这是因为嵌套的Metadata类没有被Mongoose识别为合法的子Schema,导致内部的@Prop配置完全失效。

修复步骤

  • 给Metadata类添加@Schema()装饰器,明确它是一个Mongoose子Schema
  • 在User类的metadata字段中,用SchemaFactory.createForClass(Metadata)替代直接传入Metadata类作为类型

修正后的代码示例

import { Schema, Prop, SchemaFactory } from '@nestjs/mongoose';
import mongoose from 'mongoose';
import { Role } from './role.schema';
import { Favourite } from './favourite.schema';

@Schema() // 新增装饰器,标记为子Schema
class Metadata {
  @Prop({
    ref: 'Role',
    type: [mongoose.Schema.Types.ObjectId],
    default: [] // 显式指定默认空数组,确保文档创建时自动生成
  })
  roles: Role[];
}

@Schema({...})
export class User {
  @Prop()
  name: string;

  @Prop()
  password: string;

  @Prop({
    ref: 'Favourite',
    type: [mongoose.Schema.Types.ObjectId]
  })
  favourties: Favourite[]

  @Prop({ type: SchemaFactory.createForClass(Metadata) }) // 修改为SchemaFactory生成的子Schema类型
  metadata: Metadata;

  @Prop({
    ref: 'Role',
    type: [mongoose.Schema.Types.ObjectId]
  })
  roles: Role[];
}

原理说明

当你直接在@Prop里传入普通类作为类型时,Mongoose只会把它当作普通嵌套对象处理,不会解析类内部的@Prop装饰器配置。给Metadata加上@Schema()并通过SchemaFactory.createForClass生成子Schema后,Mongoose才能正确识别内部的引用规则,默认空数组的行为也会同步生效。显式添加default: []则是进一步确保文档创建时该字段的默认值存在。

内容的提问来源于stack exchange,提问作者Unknown User

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 14:35:22