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;
};
'Web Programming > NestJS' 카테고리의 다른 글
[NestJS] AWS Elastic BeanStalk 배포 (0) | 2022.02.23 |
---|---|
[NestJS] string을 mongo ObjectId로 변경하기 (0) | 2022.02.23 |
[NestJS] 아직도 dotenv 사용함? (0) | 2022.02.03 |
[NestJS] Mongoose pre, post hook 설정 (0) | 2022.02.03 |
[NestJS] DTO(Data Transfer Object)를 이용한 Validation (0) | 2022.02.03 |