mongodb 带有schema数组的NestJS mongoose schema不填充虚拟id

yvfmudvl  于 11个月前  发布在  Go
关注(0)|答案(1)|浏览(124)

我有以下模式

export type MapDocument = Map & Document

@Schema({ 
  timestamps: true, 
  versionKey: false,
  id: true
})
export class Map {
  
  constructor(partial?: Partial<Map>) {
    if (partial)
      Object.assign(this, partial)
  }

  @IsOptional()
  @IsUUID()
  @Prop({ type: Object, default: uuidv4, required: false})
  @Exclude({ toPlainOnly: true })
  _id?: Object

  @ApiPropertyOptional({ type: String, format: 'uuid' })
  @IsOptional()
  @IsUUID()
  id?: string

  @ApiProperty()
  @IsAscii()
  @MaxLength(10)
  @Prop()
  building: string

  @ApiProperty()
  @IsInt()
  @Prop()
  @Transform(({ value }) => +value, { toClassOnly: true })  
  floor: number

  @ApiPropertyOptional({ type: Image, format: 'uuid'})
  @IsOptional()
  @IsUUID()
  @Prop({ type: String, ref: 'Image' })
  @Transform(({ value }) => new Image(value).id, { toClassOnly: true })
  image?: string

  @ApiProperty({ type: [Marker] })
  @IsArray()
  @Type(() => Marker)
  @Prop({ type: [MarkerSchema] })
  markers?: Marker[]
  
}

const MapSchema = SchemaFactory.createForClass(Map)
MapSchema.index({ building: 1, floor: 1 }, { unique: true });
const mongooseLeanVirtuals = require('mongoose-lean-virtuals')
MapSchema.plugin(mongooseLeanVirtuals);
export { MapSchema }

export class UpdateMap extends PartialType(Map) {}

字符串
标记声明如下

export type MarkerDocument = Marker & Document

@Schema({ 
  timestamps: true, 
  versionKey: false,
  id: true
})
export class Marker {
  
  constructor(partial?: Partial<Marker>) {
    if (partial)
      Object.assign(this, partial)
  }

  @IsOptional()
  @IsUUID()
  @Prop({ type: Object, default: uuidv4, required: false})
  @Exclude({ toPlainOnly: true })
  _id?: Object

  @ApiPropertyOptional({ type: String, format: 'uuid' })
  @IsOptional()
  @IsUUID()
  id?: string

  @ApiPropertyOptional({ type: Desk, format: 'uuid'})
  @IsOptional()
  @IsUUID()
  @Prop({ type: String, required: false, ref: 'Desk' })
  @Transform(({ value }) => new Desk(value).id, { toClassOnly: true })
  desk?: string

  @ApiProperty()
  @IsNumberString()
  @Prop()
  xPercent: string

  @ApiProperty()
  @IsNumberString()
  @Prop()
  yPercent: string
  
}

const MarkerSchema = SchemaFactory.createForClass(Marker)
const mongooseLeanVirtuals = require('mongoose-lean-virtuals')
MarkerSchema.plugin(mongooseLeanVirtuals);
export { MarkerSchema }

export class UpdateMarker extends PartialType(Marker) {}


重要的是要注意,有一个字段(desk)引用另一个集合,但我不希望这些项目存储在自己的集合中,而是直接作为“maps”集合的子文档
“desk”模式声明如下

export type DeskDocument = Desk & Document

@Schema({ 
  timestamps: true, 
  versionKey: false,
  id: true
})
@ApiExtraModels(Image)
export class Desk {

  constructor(partial?: Partial<Desk>) {
    if (partial)
      Object.assign(this, partial)
  }
  
  @IsOptional()
  @IsUUID()
  @Prop({ type: Object, default: uuidv4, required: false})
  @Exclude({ toPlainOnly: true })
  _id?: Object

  @ApiPropertyOptional({ type: String, format: 'uuid' })
  @IsOptional()
  @IsUUID()
  id?: string

  @ApiProperty({ type: Board, format: 'uuid'})
  @IsUUID('all')
  @Prop({ type: String, required: true, ref: 'Board' })
  @Transform(({ value }) => value.id, { toClassOnly: true })
  board: string

  @ApiProperty({ type: [Number] })
  @IsArray()
  @Prop({ type: () => [Number], required: true })
  relays?: number[]

  @ApiProperty()
  @IsAscii()
  @MaxLength(250)
  @Prop()
  name: string

  @ApiProperty()
  @IsAscii()
  @MaxLength(250)
  @Prop()
  description: string

  @ApiProperty()
  @IsAscii()
  @MaxLength(10)
  @Prop()
  building: string

  @ApiProperty()
  @IsInt()
  @Prop()
  @Transform(({ value }) => +value, { toClassOnly: true })  
  floor: number

  @ApiProperty()
  @IsAscii()
  @MaxLength(10)
  @Prop()
  code: string

  @ApiPropertyOptional({ type: [Image], format: 'uuid'})
  @IsOptional()
  @IsUUID('all', { each: true })
  @Prop({ type: [String], required: false, ref: 'Image' })
  @Transform(({ value }) => value.id, { toClassOnly: true })
  images?: String[]

}

const DeskSchema = SchemaFactory.createForClass(Desk)
DeskSchema.index({ board: 1, relays: 1 }, { unique: true });
const mongooseLeanVirtuals = require('mongoose-lean-virtuals')
DeskSchema.plugin(mongooseLeanVirtuals)

export { DeskSchema }

export class UpdateDesk extends PartialType(Desk) {}


find方法试图将所有内容填充到desk中(我不需要填充得更深)

async findAll(): Promise<Map[]> {
    return (await this.mapModel.find().populate({
      path: 'image',
      model: Image,
      transform: (doc: Image) => new Image(doc),
    }).populate({
      path: 'markers',
      model: Marker,
      transform: (doc: Marker) => new Marker(doc),
      populate: {
        path: 'desk',
        model: Desk,
        transform: (doc: Desk) => new Desk(doc),
        options: { lean: true, virtuals: true },
      }
    }).lean({ virtuals: true }).exec())
    .map(map => new Map(map))
  }

两个问题

1.次要:如果我不指定lean:true作为desk populate的一个选项,我得到了完整的mongo文档。这不是'markers'数组的情况,它依赖于'lean'设置
1.Main:desk对象被填充,但virtual 'id'字段没有。这是我得到的输出:

{
  "building": "A",
  "floor": 1,
  "image": {
    "name": "OfficePlan12",
    "url": "https://drive.google.com/uc?id=1H2nnIRjR2e7Z7yoVnHxLCTaYs8s5iHrT",
    "updatedAt": "2022-06-24T09:03:03.786Z",
    "id": "2b31f419-e069-4058-813e-54ce0a941440"
  },
  "updatedAt": "2022-06-26T10:19:22.650Z",
  "markers": [
    {
      "yPercent": "15.853658536585366",
      "xPercent": "18.083462132921174",
      "desk": {
        "images": [
          "b85eefee-eeca-4193-87ae-9329fad8256a",
          "692743d0-a860-4451-b313-b21a144ef387"
        ],
        "description": "Work like a boss",
        "name": "Management desk",
        "createdAt": "2022-02-19T21:12:18.832Z",
        "updatedAt": "2022-06-07T14:02:13.556Z",
        "building": "A",
        "code": "01",
        "floor": 1,
        "relays": [
          "1"
        ],
        "board": "932c3e9b-85bd-42c8-9bc0-a318eea7b036"
      },
      "updatedAt": "2022-06-26T10:19:22.650Z",
      "createdAt": "2022-06-26T10:19:22.650Z",
      "id": "a8149e84-2f62-46c3-990f-531eff82f6d5"
    }
  ],
  "id": "37dc791f-724b-44e2-baaf-bfc606385996"
}


正如你所看到的,desk对象没有id字段。任何帮助都将非常感激,谢谢!

nhaq1z21

nhaq1z211#

我终于找到了一个解决方法。公平地说,它看起来很糟糕,但它确实有效。基本上,我修改了“桌面”文档的transform函数,它是我的“内部”文档“image”的第一个“外部”文档。该函数如下所示:

transform: (doc: Desk) => new Desk((new this.deskModel(doc)).toObject({ virtuals: true })),
    options: { lean: true },
    populate: {
      path: 'images',
      model: Image,
      transform: (doc: Image) => new Image(doc)
    }

字符串
基本上,我需要在服务构造函数中注入相应的模型,以便能够使用“options”和“populate”调用“toObject”函数。最后,我需要使用获得的对象构建一个新的“Desk”示例,以确保类验证函数正确应用于我的端点。希望这将帮助某人,也许有人可以提出一个更优雅的解决方案。

相关问题