• 카테고리

    질문 & 답변
  • 세부 분야

    백엔드

  • 해결 여부

    해결됨

하나만 더 질문드릴게요!

21.09.13 17:54 작성 조회수 128

2

아까의 답변으로 한참 고생했던게 해결됬습니다.

제가 JS를 시작한지 얼마 안되서 사용법을 잘 모르겠는데 예를들어

let user = {};

user.id = 123; 을 입력하면

user = { id: 123} 이렇게 잘 나옵니다.

그리고 mongoose에서 user 문서 내부의 info Object안에 있는 id를 변경할 때에는

$set {"info.id" : ~~~} 이런식으로 변경하는걸로 알고있습니다.

그걸 updateBody 안에 모아서 한번에 쏴주고싶은데

어떤 식을 써야 updateBody = { "info.id": ~~ } 이같은 형식의 데이터가 만들어지는지 모르겠습니다.

제가 시도한 코드

let updateBody = {};

updateBody."info.id" = 123   -실패

 

updateBody.push({ "info.id": 123}) , updateBody.insert({ "info.id": 123}) 또한 실패했습니다.

답변 2

·

답변을 작성해보세요.

1

유성현님의 프로필

유성현

질문자

2021.09.14

감사합니다ㅎㅎ 답변 달아주신거 보고 해결했습니다.

( 앱 모달창으로 한번에 하나의 item만 수정할 수 있습니다. )

export const ReviseCafeData = async (params: any) => {
try {
const { cafe_id, introduction, beans, phone } = params;
let updateBody: any = {};
if (introduction && !beans && !phone) updateBody = { 'cafe_info.introduction': introduction };
else if (!introduction && beans && !phone) updateBody = { 'cafe_info.beans': beans };
else if (!introduction && !beans && phone) updateBody = { 'cafe_info.phone': phone };
else console.log('데이터가 하나만 등록되어야 함'); // 배포 시 return err 처리
return await CafeModel.findOneAndUpdate({ cafe_id }, updateBody, { new: true });
} catch (err) {
console.log(err);
return { err };
}
};

0

유성현님 안녕하세요 :)

아래처럼 여러 값들을 입력해주시면 하시면 됩니다. 그리고 $set은 생략하셔도 되요. 몽구스가 중간에 $set을 입력해줍니다.

const user = await User.findOneAndUpdate({ _id: userId }, { 'info.id': newId, 'info.name': newName })

그리고 'info.id'이렇게 표시한 이유는 Javascript에서 가능하지 않은 문법이기 때문이에요.

그래서 key를 텍스트로 해서 info 객체 안에 있는 id를 newId로 변환해달라는 의미에서 저렇게 표시해주는겁니다. 그러면 몽고디비에서 해당 키를 파싱 해서 올바르게 업데이트 처리를 해줍니다!

마찬가지로 전에 설명드렸던 $도 JS문법은 아니고 몽고디비가 파싱해서 사용합니다.

const user = await User.findOneAndUpdate(
{ _id: userId, 'friends._id': friendId },
{ 'info.id': newId, 'info.name': newName, 'friends.$.name': newFriendName },
{ new: true }
)

이렇게 업데이트를 하면 info 객체 안에 있는 id, name도 업데이트가 되고 friends 배열 안에 _id가 friendId인 객체의 name도 newFriendName으로 업데이트 해줍니다. 배열 안에 특정 객체를 업데이트할 때 $를 표시해주는건 배열에 포함되어 있는데 모든 객체가 아니라 특정 객체임을 표시해주기 위함이에요!

만약 'friends.name': newFriendName으로 하게 되면 해당 배열에 있는 모든 객체의 name들이 업데이트되게 됩니다!

 

그리고 updateBody를 따로 사용한 이유는 API 요청 조건에 따라 findOneAndUpdate에서 두번째 인자(업데이트 객체)가 바뀔 수 있기 때문이에요. 아래 두 코드는 완벽하게 동일한 코드입니다!

 

const user = await User.findOneAndUpdate(
{ _id: userId, 'friends._id': friendId },
{ 'info.id': newId, 'info.name': newName, 'friends.$.name': newFriendName },
{ new: true }
)

 

const updateBody = { 'info.id': newId, 'info.name': newName, 'friends.$.name': newFriendName }
const user = await User.findOneAndUpdate(
{ _id: userId, 'friends._id': friendId },
updateBody,
{ new: true }
)