오히려 좋아..

상황이 나쁘게만 흘러가는 것 같을 때 외쳐보자.. .

궁금한 마음으로 포트폴리오 보기

Web Programming/NestJS

[NestJS] mongoose 다른 이름으로 populate하기

junha6316 2022. 2. 14. 22:10

mongoose 네이밍 컨벤션중에 다른 collection을 참조하는 필드의 경우 id를 붙여주는 컨벤션이 있다. 의미상 당연히 ObjectId가 들어가기 때문에 적절한 컨벤션이라고 생각한다. 하지만 문제는 populate할 때 발생한다. populate는 일종의 RDBMS의 join과 같은 것으로 참조하는 collection에서 document를 묶어서 가져오는 메서드이다. 저장되는건 userId인데 실제로 populate한 이후에는 UserDocument가 되기 때문이다. 그래서 아래와 같은 상황이 매번 벌어진다

const order = this.orderRepository.getById(orderId).populate('userId')
console.log(order.userId.name)
console.log(order.userId.id)

적혀있는건 userId이지만 실제로는 UserDocument가 들어가 있는 형태이다. 이를 해결해주려면 virtual 메서드를 사용해주면 된다.

 

export type OrderDocument = Order & mongoose.Document 

export class Order {
	
    @Prop()
    name: string
    
    @Prop()
    productId: ObjectId
    
    @Prop()
    userId: ObjectId
   
}

export const OrderSchema = SchemaFactory.createForClass(Order);


OrderSchema.virtual("user", {
  ref: "User",  // 참조할 collections
  localField: "userId", // 현재 스키마에 선언되어 있는 참조할 필드
  foreignField: "_id", // collections에서 참조할 필드
  justOne: true, // 하나만 반환하는지 여부
});

자 이제 아래와 같이 사용할 수 있다.

const order = this.orderRepository.getById(orderId).populate('user')
console.log(order.user.name)
console.log(order.user.id)

 

 

이렇게 하다가 type 에러가 날 수 있다. 그렇다면 아래처럼 해주자

export type OrderDocument = Order & mongoose.Document & {
    user: UserDocument;
  };