반응형
문제상황
http patch메서드를 사용하는 도중 받은 데이터가 존재하는 경우에 대해서만 필드를 업데이트 해야 하는 경우가 생겼다.
받은 데이터가 null이나 undefined이면 기존 데이터 그대로 저장하고, 받은 데이터가 존재한다면 새로운 값을 저장하는 쿼리를 만들었다
예시 Document
// User document
{
name: 'test',
age: 27,
status: 'A',
group: 'TEST'
}
mongoose를 사용한 해결 방법
JavaScript
const updateUser = async (profile) =>{
// 해당 필드가 있을때 해당필드만 업데이트해주는 쿼리
const updateQuery = {
$set: {
// profile.name이 null또는 undefined면 기존 name을 저장
// 아니면 profile.name에 있는 값을 저장
'name': {$cond: [{$not: [!profile.name]}, profile.name, '$name']},
'age': {$cond: [{$not: [!profile.age]}, profile.age, '$age']},
'status': {$cond: [{$not: [!profile.status]}, profile.status, '$status']},
'group': {
$cond: [{$not: [!profile.group]}, profile.group, '$group'],
},
},
};
const user = await User.findOneAndUpdate(
// 조건문 _id가 profile._id인 document를 찾아서 update
{
_id: profile._id,
},
// 배열 안에 updateQuery를 넣는 이유: aggregation을 위해
[updateQuery],
{
// update를 적용한 결과를 return
new: true,
}
);
return user;
}
updateUser({_id: 'test', age: 30})
// return
// {
// _id: 'test'
// name: 'test',
// age: 30,
// status: 'A',
// group: 'TEST'
// }
updateUser({_id: 'test', name: 'test2'})
// return
// {
// _id: 'test'
// name: 'test2',
// age: 30,
// status: 'A',
// group: 'TEST'
// }
updateUser({_id: 'test', age: 35, name: 'test3', group: 'test2'});
// return
// {
// _id: 'test'
// name: 'test3',
// age: 35,
// status: 'A',
// group: 'test2'
// }
TypeScript
type Profile = {
_id: string
name?: string | null | undefined,
age?: number | null | undefined,
status?: string | null | undefined
group?: string | null | undefined
}
const updateUser = async (profile: Profile) =>{
// 해당 필드가 있을때 해당필드만 업데이트해주는 쿼리
const updateQuery: { [key: string]: any } = {
$set: {
// profile.name이 null또는 undefined면 기존 name을 저장 아니면 profile.name에 있는 값을 저장
'name': {$cond: [{$not: [!profile.name]}, profile.name, '$name']},
'age': {$cond: [{$not: [!profile.age]}, profile.age, '$age']},
'status': {$cond: [{$not: [!profile.status]}, profile.status, '$status']},
'group': {
$cond: [{$not: [!profile.group]}, profile.group, '$group'],
},
},
};
const user = await User.findOneAndUpdate(
// 조건문 _id가 profile._id인 document를 찾아서 update
{
_id: profile._id,
},
// 배열 안에 updateQuery를 넣는 이유: aggregation을 위해
[updateQuery],
{
// update를 적용한 결과를 return
new: true,
}
);
return user;
}
updateUser({_id: 'test', age: 30})
// return
// {
// _id: 'test'
// name: 'test',
// age: 30,
// status: 'A',
// group: 'TEST'
// }
updateUser({_id: 'test', name: 'test2'})
// return
// {
// _id: 'test'
// name: 'test2',
// age: 30,
// status: 'A',
// group: 'TEST'
// }
updateUser({_id: 'test', age: 35, name: 'test3', group: 'test2'});
// return
// {
// _id: 'test'
// name: 'test3',
// age: 35,
// status: 'A',
// group: 'test2'
// }
shell에서의 해결방법
db.getCollection("User").findOneAndUpdate(
// 조건문 _id가 'test'인 document를 찾아서 update
{
_id: 'test',
},
// 배열 안에 updateQuery를 넣는 이유: aggregation을 위해
[{
$set: {
// true면 test2를 저장 false면 기존 name을 저장
'name': { $cond: [true, 'test2', '$name'] },
'age': { $cond: [false, profile.age, '$age'] },
'status': { $cond: [false, profile.status, '$status'] },
'group': {
$cond: [false, profile.group, '$group'],
},
},
}],
{
// update를 적용한 결과를 return
returnNewDocument: true,
}
);
// {
// _id: 'test'
// name: 'test2',
// age: 27,
// status: 'A',
// group: 'TEST'
// }
반응형
'DataBase > MongoDB' 카테고리의 다른 글
[Mongoose] mongoose 에서 statics method와 instance method의 차이점 (0) | 2022.07.14 |
---|---|
[Mongoose] mongoose 사용시 save가 느린 현상 해결 방법 (0) | 2022.07.03 |
[MongoDB] MongoDB Version Upgrade 하는 방법 (Standalone) (0) | 2022.05.12 |
[MongoDB] MongoDB에서 계정 생성 (0) | 2022.05.10 |
[MongoDB] linux(unbuntu)에 mongodb 설치하기 (0) | 2022.05.08 |