NestJS MongoDB 嵌套对象模式

Posted

技术标签:

【中文标题】NestJS MongoDB 嵌套对象模式【英文标题】:NestJS MongoDB nested object schema 【发布时间】:2021-06-21 01:31:33 【问题描述】:

我目前正在运行代码:

export class SystemInformationContent 
  createdAt: number;

  createdBy: User | mongoose.Schema.Types.ObjectId | null;

  updatedAt?: number;

  updatedBy?: User | mongoose.Schema.Types.ObjectId | null;


@Schema()
export class SystemInformation 
  @Prop(
    raw(
      createdAt:  type: Number, required: true ,
      createdBy:  type: mongoose.Schema.Types.ObjectId, ref: 'User' ,
      updatedAt:  type: Number, default: 0 ,
      updatedBy: 
        type: mongoose.Schema.Types.ObjectId,
        ref: 'User',
        default: null,
      ,
    ),
  )
  system: SystemInformationContent;

我没有找到任何“扩展”SystemInformationContent 架构的方法,因此在@Prop() 装饰器中使用了raw() 函数,但我想知道是否有办法做这样的事情:

export class SystemInformationContent 
  @Prop( required: true )
  createdAt: number;

  @Prop( type: mongoose.Schema.Types.ObjectId, ref: 'User' )
  createdBy: User | mongoose.Schema.Types.ObjectId | null;

  @Prop( default: 0 )
  updatedAt?: number;

  @Prop( type: mongoose.Schema.Types.ObjectId, ref: 'User', default: null )
  updatedBy?: User | mongoose.Schema.Types.ObjectId | null;


@Schema()
export class SystemInformation 
  @Prop(???)
  system: SystemInformationContent;

考虑到SystemInformationContent 的架构,我没有发现任何可以放入SystemInformation.system @Prop() 的内容。

你们知道除了raw 之外是否还有其他方法,或者我是否遗漏了什么?

编辑:我的 NestJS 应用程序的所有类都在扩展 SystemInformation,所以它们看起来都像:


  ...,
  system: 
    createdAt: 1616778310610,
    createdBy: "605e14469d860eb1f0641cad",
    editedAt: 0,
    createdBy: null,
  ,

【问题讨论】:

【参考方案1】:

找到了解决办法!

我将SystemInformationContent 编辑为:

import  Prop, Schema, SchemaFactory  from '@nestjs/mongoose';
import * as mongoose from 'mongoose';
import  User  from '~/schemas/user.schema';

@Schema( _id: false )
export class SystemInformationContent 
  @Prop( type: Number, required: true )
  createdAt: number;

  @Prop( type: mongoose.Schema.Types.ObjectId, ref: 'User' )
  createdBy: User;

  @Prop( type: Number, default: 0 )
  updatedAt?: number;

  @Prop(
    type: mongoose.Schema.Types.ObjectId,
    ref: 'User',
    default: null,
  )
  updatedBy?: User;


export const SystemInformationContentSchema = SchemaFactory.createForClass(
  SystemInformationContent,
);

然后在 SystemInformation 中我编辑为:

import  Prop, Schema  from '@nestjs/mongoose';
import 
  SystemInformationContent,
  SystemInformationContentSchema,
 from '~/schemas/systemInformationContent.schema';

@Schema()
export default class SystemInformation 
  @Prop( required: true, type: SystemInformationContentSchema )
  system: SystemInformationContent;

现在一切正常,我使用@Schema( _id: false ) 删除了 SchemaFactory 生成的 ID,所以我最终在数据库中得到了它:


  ...,
  "system": 
    "updatedBy": null,
    "updatedAt": 0,
    "createdAt": 1616847116986,
    "createdBy": 
      "$oid": "605f210cc9fe3bcbdf01c95d"
    
  ,
  ...,

【讨论】:

【参考方案2】:

如果您使用typegoose(7.0 或更高版本),那么您当前拥有的应该足够了,如果您在 tsconfig 中启用了emitDecoratorMetadata

typegoose 示例(下面的代码使用 ~7.4 的选项扩展):

export class SystemInformationContent 
  @Prop( required: true )
  createdAt: number;

  @Prop( type: mongoose.Schema.Types.ObjectId, ref: () => User )
  createdBy: Ref<User>;

  @Prop( default: 0 )
  updatedAt?: number;

  @Prop( type: mongoose.Schema.Types.ObjectId, ref: () => User ) // default is "undefined"
  updatedBy?: Ref<User>;


export class SystemInformation 
  @Prop() // thanks to "emitDecoratorMetadata" no explicit types are needed 
  system: SystemInformationContent;

  // but if wanting to do explicit types
  @Prop( type: () => SystemInformationContent )
  system: SystemInformationContent;

PS:我不知道你的函数raw来自哪里,但这不是typegoose函数

【讨论】:

嗨,我正在使用 NestJS,它使用自己的 goose 类型实现 (github.com/kpfromer/nestjs-typegoose) 非常感谢您的回答,我会调查的! 我尝试了您的解决方案,但它不起作用,emitDecoratorMetadata 已启用,但我认为 NestJS typegoose 不能那样工作......【参考方案3】:

如果我做对了,这就是你想要的。您只错过了 SystemInformationContent@Schema() 注释,并且需要在任何您想要的地方继承此模式。我有一个类似的问题。所以,如果这不是您要求的,请告诉我。

@Schema()
export class SystemInformationContent 
  // put your @Prop() attributes here, that need to be available in every other schema


@Schema()
export class SystemInformation extends SystemInformationContent 
  // no need to do anything else here
  // the attributes are inherited from SystemInformationContent 

【讨论】:

嘿伙计,这不是我正在寻找的解决方案,但由于某种原因,您的回答让我在脑海中解开了一些东西,让我找到了解决方案,非常感谢!

以上是关于NestJS MongoDB 嵌套对象模式的主要内容,如果未能解决你的问题,请参考以下文章

NestJS TypeORM MongoDB 无法使用 find 或 FindOne 搜索存储库

如何从 MongoDB 的嵌套对象中获取特定细节

如何在nestjs mongoose typescript中引用嵌套文档

填充嵌套数组的无引用对象

无法连接到数据库 - Mongoose nestJS

如何使用 NestJS 命名法为猫鼬写下嵌套模式 [关闭]