백엔드
[mongodb] 메서드 및 문법 정리
ehddkDEV
2024. 11. 15. 09:52
1.findByIdAndUpdate()
findByIdAndUpdate(
id, // 첫 번째 매개변수: 업데이트할 문서의 ID
{ $set: { ... } }, // 두 번째 매개변수: 업데이트할 내용
{ new: true } // 세 번째 매개변수: 옵션
)
ex> 배송지 등록
프로젝트에서 배송지 등록을 구현해야하는 부분이 있어서 서비스 부분에
해당 메서드를 사용해야했다! 배송지를 등록하고 유저 프로필에 업데이트를 해줘야하기 때문이다!
async createDelivery(userId: string,delivery:Omit<IDelivery,"id">):Promise<DeliveryResponseDTO>{
console.log('userId',userId)
try{
//1. 유저 찾기
const user = await this._userRepository.findById(userId);
if (!user) {
throw new Error('해당 유저를 찾을 수 없습니다.');
}
console.log('유저 찾기 :',user)
//2. 배송지 생성하기
const newDelivery=await this._deliveryRepository.save(
userId,
delivery
)
console.log('배송지의 userId:', newDelivery.userId);
const updatedProfile = await MongooseProfile.findByIdAndUpdate(
user.profile,
{ $set: { delivery: newDelivery} },
{ new: true }
).exec();
console.log('Updated profile:', updatedProfile);
return newDelivery;
}catch(error){
throw new Error('배송지 등록 중 오류 발생하였습니다.')
}
}
위 코드에서 일부분만 본다면
const updatedProfile = await MongooseProfile.findByIdAndUpdate(
user.profile,
{ $set: { delivery: newDelivery} },
{ new: true }
).exec();
console.log('Updated profile:', updatedProfile);
return newDelivery;
user.profile을 Id로 잡고 delivery에 새로운 배송지인 newDelivery를 담는것이다.
{ new: true }를 함으로써 새로운 내용을 반환하게 된다.
이때 ,$set을 생략해도 동일하게 작동한다!
2. $push, $set
{ $push: { <field1>: <value1>, ... } }
$push 연산자는 지정된 값을 배열에 추가한다.
$set 연산자는 기존내용이 새로운 내용으로 계속 덮어씌어진다.
한 유저에 배송지를 계속 추가할 수 있게 스키마나 모델부분에도 배열로 설정하고 했는데도 추가가 아니라 계속 새로운 값으로 나오는거다..
알고보니 $set 연산자를 사용했고 , 그래서 유심히 살펴보니 $push 연산자가 따로 있던 것!!
async createDelivery(userId: string,delivery:Omit<IDelivery,"_id">):Promise<DeliveryResponseDTO>{
//새로운 배송지
const newDelivery=await this._deliveryRepository.save(
userId,
delivery
)
const updatedProfile = await MongooseProfile.findByIdAndUpdate(
user.profile.id,
{ $push: { delivery:newDelivery} }, //delivery에 새로운배송지 등록.추가
{ new: true } // 새로운 내용을 반환
).exec();
}
3. populate
테이블끼리 join을 하다보면 중첩 Populate를 하곤한다..
User -> profile -> delivery
예를 들어 유저 안에 프로필이 있고 그 안에 주소(배송지)부분이 있어서..서로 참조해야하는..
await MongooseUser.findById(userId)
.populate({
path: 'profile',
populate: [
{
path: 'delivery',
model: 'Delivery'
},
{
path: '다른필드',
model: '다른모델'
}
]
})
.exec();
이런 식으로 path에는 실제 참조하고 있는 필드명, model에는 스키마 모델을 작성하면 된다.
참조가 잘 안되면 아예 값이 안들어오더라...