Nest.js의 Mongoose 하위 문서

LBeerus

내 앱을 express.js에서 Nest.js로 옮기고 있는데 mongoose.Schema ({...})로 Schema를 선언하는 오래된 방법을 사용하지 않고 다른 mongoose Schema를 참조하는 방법을 찾을 수 없습니다.

문서의 예제를 사용하여 문제를 명확히 할 수 있습니다.

@Schema()
  export class Cat extends Document {
  @Prop()
  name: string;
}

export const CatSchema = SchemaFactory.createForClass(Cat);

이제 내가 원하는 것은 다음과 같습니다.

@Schema()
export class Owner extends Document {
  @Prop({type: [Cat], required: true})
  cats: Cat[];
}

export const OwnerSchema = SchemaFactory.createForClass(Owner);

이런 방식으로 스키마를 정의하면 다음과 같은 오류가 발생합니다. 잘못된 스키마 구성 : Cat배열 내에서 유효한 유형이 아닙니다.cats

그렇다면 스키마를 정의하는 데 더 많은 OO 접근 방식을 사용하여 한 스키마를 다른 스키마 내부에서 참조하는 적절한 방법은 무엇입니까?

에드워드 안토니

나는 소스 코드를 파헤쳐 서 Schema 클래스가 SchemaFactory.createForClass메소드에 의해 어떻게 변환되는지 배웠다 .

그럼 어떻게 작동합니까?

1. 아래의 예를 살펴보십시오.

@Schema()
export class Cat extends Document {
  @Prop()
  name: string;
}
export const catSchema = SchemaFactory.createForClass(Cat);

기본적으로 할 때 SchemaFactory.createForClass(Cat)

Nest는 클래스 구문을 Mongoose 스키마 구문으로 변환하므로 결국 변환 결과는 다음과 같습니다.

const schema = new mongoose.Schema({
    name: { type: String } // Notice that `String` is now uppercase.
});

2. 변환은 어떻게 작동합니까?

이 파일을보세요 : mongoose / prop.decorator.ts at master · nestjs / mongoose · GitHub

export function Prop(options?: PropOptions): PropertyDecorator {
  return (target: object, propertyKey: string | symbol) => {
    options = (options || {}) as mongoose.SchemaTypeOpts<unknown>;

    const isRawDefinition = options[RAW_OBJECT_DEFINITION];
    if (!options.type && !Array.isArray(options) && !isRawDefinition) {
      const type = Reflect.getMetadata(TYPE_METADATA_KEY, target, propertyKey);

      if (type === Array) {
        options.type = [];
      } else if (type && type !== Object) {
        options.type = type;
      }
    }

    TypeMetadataStorage.addPropertyMetadata({
      target: target.constructor,
      propertyKey: propertyKey as string,
      options,
    });
  };
}

여기서 Prop()데코레이터가 씬 뒤에서하는 일을 볼 수 있습니다 . 당신이 할 때 :

@Prop()
name: string;

Prop 이 경우 인수없이 함수가 호출됩니다.

const type = Reflect.getMetadata(TYPE_METADATA_KEY, target, propertyKey);

ReflectAPI를 사용하면 .NET을 실행할 때 사용하는 데이터 유형을 가져올 수 있습니다 name: string. type이제 변수 이로 설정됩니다 String. 그렇지 않은 string경우 ReflectAPI는 항상 데이터 유형의 생성자 버전을 반환하므로 다음과 같습니다.

  • number 다음과 같이 직렬화됩니다. Number
  • string 다음과 같이 직렬화됩니다. String
  • boolean 다음과 같이 직렬화됩니다. Boolean
  • 등등

TypeMetadataStorage.addPropertyMetadata 그런 다음 아래의 개체를 저장소에 저장합니다.

{
    target: User,
    propertyKey: ‘name’,
    options: { type: String }
}

다음을 살펴 보겠습니다 : mongoose / type-metadata.storage.ts at master · nestjs / mongoose · GitHub

export class TypeMetadataStorageHost {
  private schemas = new Array<SchemaMetadata>();
  private properties = new Array<PropertyMetadata>();

  addPropertyMetadata(metadata: PropertyMetadata) {
    this.properties.push(metadata);
  }
}

그래서 기본적으로 그 개체가에 저장됩니다 properties의 변수 TypeMetadataStorageHost. TypeMetadataStorageHost이러한 객체를 많이 저장할 싱글 톤입니다.

3. 스키마 생성

SchemaFactory.createForClass(Cat)Mongoose 스키마를 생성하는 방법을 이해하려면 다음을 참조하십시오. mongoose / schema.factory.ts at master · nestjs / mongoose · GitHub

export class SchemaFactory {
  static createForClass(target: Type<unknown>) {
    const schemaDefinition = DefinitionsFactory.createForClass(target);
    const schemaMetadata = TypeMetadataStorage.getSchemaMetadataByTarget(
      target,
    );
    return new mongoose.Schema(
      schemaDefinition,
      schemaMetadata && schemaMetadata.options,
    );
  }
}

가장 중요한 부분은 : const schemaDefinition = DefinitionsFactory.createForClass(target);. 여기에서 대상은 Cat클래스입니다.

여기에서 메소드 정의를 볼 수 있습니다 : mongoose / definitions.factory.ts at master · nestjs / mongoose · GitHub

export class DefinitionsFactory {
  static createForClass(target: Type<unknown>): mongoose.SchemaDefinition {
    let schemaDefinition: mongoose.SchemaDefinition = {};

  schemaMetadata.properties?.forEach((item) => {
    const options = this.inspectTypeDefinition(item.options as any);
    schemaDefinition = {
    [item.propertyKey]: options as any,
      …schemaDefinition,
    };
  });

    return schemaDefinition;
}

schemaMetadata.properties저장했을 때 저장 한 객체를 포함합니다 TypeMetadataStorage.addPropertyMetadata.

[
    {
        target: User,
        propertyKey: ‘name’,
        options: { type: String }
    }
]

다음 forEach을 생성합니다.

{
    name: { type: String }
}

결국 master · nestjs / mongoose · GitHub에서mongoose.Schema 생성자 mongoose / schema.factory.ts에 대한 인수로 사용됩니다 .

return new mongoose.Schema(
    schemaDefinition,
    schemaMetadata && schemaMetadata.options,
);

4. 따라서 질문에 답하려면 :

Prop()논쟁 으로 무엇을 넣어야 합니까?

Nest가 forEachMongoose 스키마를 생성하는 시기를 기억 하십니까?

schemaMetadata.properties?.forEach((item) => {
  const options = this.inspectTypeDefinition(item.options as any);
  schemaDefinition = {
    [item.propertyKey]: options as any,
    …schemaDefinition,
  };
});

options그것을 얻으려면 inspectTypeDefinition방법 을 사용하십시오 . 아래 정의를 볼 수 있습니다.

private static inspectTypeDefinition(options: mongoose.SchemaTypeOpts<unknown> | Function): PropOptions {
  if (typeof options === 'function') {
    if (this.isPrimitive(options)) {
      return options;
    } else if (this.isMongooseSchemaType(options)) {
      return options;
    }
    return this.createForClass(options as Type<unknown>);   
  } else if (typeof options.type === 'function') {
    options.type = this.inspectTypeDefinition(options.type);
    return options;
  } else if (Array.isArray(options)) {
    return options.length > 0
      ? [this.inspectTypeDefinition(options[0])]
      : options;
  }
  return options;
}

여기에서 다음과 같은 결론을 내릴 수 있습니다.

  1. (가) 경우 optionsA는 function같은 String또는 SchemaType직접적 반환하고, 몽구스 옵션으로 사용됩니다.
  2. (가) 경우 optionsArray, 그 배열의 첫번째 인덱스를 반환하고 배열을 마무리한다.
  3. (가) 경우 options가 아닌 Arrayfunction, 그것은 일반 단지의 경우 예를 들어, object같은 { type: String, required: true }, 그것은 직접적으로 반환되고 몽구스 옵션으로 사용.

대답

에서 참조 추가 할 수 있도록 Cat하는 방법에 대해 Owner, 당신은 할 수 있습니다 :

import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import { Document, Schema as MongooseSchema } from 'mongoose';
import { Owner } from './owner.schema.ts';

@Schema()
export class Cat extends Document {
  @Prop()
  name: string;

  @Prop({ type: MongooseSchema.Types.ObjectId, ref: Owner.name })
  owner: Owner;
}

export const catSchema = SchemaFactory.createForClass(Cat);

에서 참조 추가하는 방법에 관해서는 Owner에를 Cat, 우리는 할 수있다 :

@Prop([{ type: MongooseSchema.Types.ObjectId, ref: Cat.name }])

최신 정보

댓글 섹션의 질문에 대한 답변 :

다른 스키마에 스키마를 삽입하는 방법은 무엇입니까?

답을 제대로 읽었다면이를 수행 할 수있는 충분한 지식이 있어야합니다. 하지만 그렇지 않은 경우 여기에 TLDR 답변이 있습니다.

여기에 가기 전에 전체 답변을 읽어 보는 것이 좋습니다.

image-variant.schema.ts

import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';

@Schema()
export class ImageVariant {
  @Prop()
  url: string;

  @Prop()
  width: number;

  @Prop()
  height: number;

  @Prop()
  size: number;
}

export const imageVariantSchema = SchemaFactory.createForClass(ImageVariant);

image.schema.ts

import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import { Document } from 'mongoose';
import { imageVariantSchema, ImageVariant } from './imagevariant.schema';

@Schema()
export class Image extends Document {
  @Prop({ type: imageVariantSchema })
  large: ImageVariant;

  @Prop({ type: imageVariantSchema })
  medium: ImageVariant;

  @Prop({ type: imageVariantSchema })
  small: ImageVariant;
}

export const imageSchema = SchemaFactory.createForClass(Image);

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

분류에서Dev

mongoose.js의 스키마 및 하위 문서

분류에서Dev

Mongoose ODM findOneAndUpdate 하위 문서

분류에서Dev

Mongoose 하위 문서 CastError

분류에서Dev

다른 잘못된 스키마 오류의 Mongoose 하위 문서

분류에서Dev

하위 문서의 참조를 채우는 방법 (Mongoose)

분류에서Dev

두 하위 문서가 모두 주 문서의 일부인 다른 하위 문서에서 Mongoose 채우기 하위 문서

분류에서Dev

Mongoose에서 하위 문서 채우기

분류에서Dev

Mongoose에서 하위 문서 정렬

분류에서Dev

req.body의 키를 사용하여 하위 문서에 Mongoose 액세스

분류에서Dev

Mongoose 하위 문서로 푸시

분류에서Dev

Mongoose 및 Express 하위 문서 API

분류에서Dev

Mongoose 쿼리 하위 문서 속성

분류에서Dev

Mongoose-하위 문서 쿼리, 부모와 자식의 요소 비교

분류에서Dev

Nest.js / mongoose 및 TypeScript-Prop 데코레이터의 오류

분류에서Dev

Mongoose에서 하위 문서를 문서의 배열로 푸시 할 수 없습니다.

분류에서Dev

node.js mongoose는 해당 문서의 현재 목록에없는 기존 문서의 하위 집합을 제거합니다.

분류에서Dev

Mongoose 및 Node.js의 JavaScript 범위 지정 문제

분류에서Dev

Mongoose 및 Express JS, 범위 내 문서 찾기

분류에서Dev

원자 쿼리를 사용하여 mongoose에서 다른 하위 문서 내의 하위 문서를 업데이트하는 방법은 무엇입니까?

분류에서Dev

Mongoose에서 하위 문서의 항목을 하나만 얻는 방법은 무엇입니까?

분류에서Dev

Mongoose에서 개체를 하위 문서의 하위 문서로 푸시 하시겠습니까? 어떻게 할 수 있습니까?

분류에서Dev

Mongo 문서 내 배열 내부의 객체를 업데이트하기위한 Mongoose 구문

분류에서Dev

Mongoose : 하위 문서 필터로 문서 찾기

분류에서Dev

Mongoose에서 하위 문서 모집단의 특정 필드를 가져 오는 방법

분류에서Dev

Mongoose에서 하위 문서와 중첩 된 개체의 차이점은 무엇입니까?

분류에서Dev

mongodb (Mongoose)에서 하위 문서의 배열 속성을 어떻게 덮어 쓸 수 있습니까?

분류에서Dev

mongoose에서 mongo 배열 하위 문서의 길이를 줄이는 효율적인 방법

분류에서Dev

Mongoose는 하위 문서의 속성을 집계하고 결과를 표시합니다.

분류에서Dev

Mongoose는 하위 문서의 필드별로 그룹화 된 값의 평균을 반환합니다.

Related 관련 기사

  1. 1

    mongoose.js의 스키마 및 하위 문서

  2. 2

    Mongoose ODM findOneAndUpdate 하위 문서

  3. 3

    Mongoose 하위 문서 CastError

  4. 4

    다른 잘못된 스키마 오류의 Mongoose 하위 문서

  5. 5

    하위 문서의 참조를 채우는 방법 (Mongoose)

  6. 6

    두 하위 문서가 모두 주 문서의 일부인 다른 하위 문서에서 Mongoose 채우기 하위 문서

  7. 7

    Mongoose에서 하위 문서 채우기

  8. 8

    Mongoose에서 하위 문서 정렬

  9. 9

    req.body의 키를 사용하여 하위 문서에 Mongoose 액세스

  10. 10

    Mongoose 하위 문서로 푸시

  11. 11

    Mongoose 및 Express 하위 문서 API

  12. 12

    Mongoose 쿼리 하위 문서 속성

  13. 13

    Mongoose-하위 문서 쿼리, 부모와 자식의 요소 비교

  14. 14

    Nest.js / mongoose 및 TypeScript-Prop 데코레이터의 오류

  15. 15

    Mongoose에서 하위 문서를 문서의 배열로 푸시 할 수 없습니다.

  16. 16

    node.js mongoose는 해당 문서의 현재 목록에없는 기존 문서의 하위 집합을 제거합니다.

  17. 17

    Mongoose 및 Node.js의 JavaScript 범위 지정 문제

  18. 18

    Mongoose 및 Express JS, 범위 내 문서 찾기

  19. 19

    원자 쿼리를 사용하여 mongoose에서 다른 하위 문서 내의 하위 문서를 업데이트하는 방법은 무엇입니까?

  20. 20

    Mongoose에서 하위 문서의 항목을 하나만 얻는 방법은 무엇입니까?

  21. 21

    Mongoose에서 개체를 하위 문서의 하위 문서로 푸시 하시겠습니까? 어떻게 할 수 있습니까?

  22. 22

    Mongo 문서 내 배열 내부의 객체를 업데이트하기위한 Mongoose 구문

  23. 23

    Mongoose : 하위 문서 필터로 문서 찾기

  24. 24

    Mongoose에서 하위 문서 모집단의 특정 필드를 가져 오는 방법

  25. 25

    Mongoose에서 하위 문서와 중첩 된 개체의 차이점은 무엇입니까?

  26. 26

    mongodb (Mongoose)에서 하위 문서의 배열 속성을 어떻게 덮어 쓸 수 있습니까?

  27. 27

    mongoose에서 mongo 배열 하위 문서의 길이를 줄이는 효율적인 방법

  28. 28

    Mongoose는 하위 문서의 속성을 집계하고 결과를 표시합니다.

  29. 29

    Mongoose는 하위 문서의 필드별로 그룹화 된 값의 평균을 반환합니다.

뜨겁다태그

보관