mongodb를 사용하여 부모 객체의 배열에 포함된 객체의 속성을 업데이트하려면 어떻게 해야 합니까?
MongoDB를 데이터베이스로 사용하고 있습니다.데이터가 있습니다.
{
_id : '123'
friends: [
{name: 'allen', emails: [{email: '11111', using: 'true'}]}
]
}
사용자 친구의 이메일을 수정하고 싶습니다.이 메일의 ID는 '123'입니다.이 메일은 다음과 같습니다.
db.users.update ({_id: '123'}, {$set: {"friends.0.emails.$.email" : '2222'} })
이메일 배열에 2개 이상의 데이터가 있는 경우, 그것은 매우 간단합니다.그래서 궁금한 것은 네스트된 파일 내의 데이터를 어떻게 수정할 수 있느냐는 것입니다.- 네스트된 배열이 2개 이상인 경우입니다.감사해요.
즉, 를 교환해야 합니다.$
업데이트하려는 요소의 제로 기반 인덱스를 사용합니다.
예를 들어 다음과 같습니다.
db.users.update ({_id: '123'}, { '$set': {"friends.0.emails.0.email" : '2222'} });
첫 번째 친구의 첫 번째 이메일이 갱신됩니다.
db.users.update ({_id: '123'}, { '$set': {"friends.0.emails.1.email" : '2222'} })
첫 번째 친구의 두 번째 이메일을 업데이트합니다.
멀티레벨 어레이를 갱신하는 유연한 방법 중 하나는 인덱스를 조회하여 식별자에 할당할 수 있는arrayFilters를 사용하는 것입니다.
db.collection.update(
{ <query selector> },
{ <update operator>: { "array.$[<identifier>].field" : value } },
{ arrayFilters: [ { <identifier>: <condition> } } ] }
)
다음은 두 개의 이메일을 통해 새 친구와 함께 제공한 예입니다.
{
_id : '123'
friends: [
{name: 'allen', emails: [
{email: '11111', using: 'true'}
]},
{name: 'lucy' , emails: [
{email: 'lucy@work.com', using:'true'},
{email:'lucyGucy@zmail.com', using : 'false'}
]}
]
}
lucyGucy@zmail.com 가 lucy.is.gucy@zmail.com 로 갱신되고 있다고 가정합니다.배열 필터의 이름 및 이메일 필드를 사용하여 업데이트할 인덱스를 식별할 수 있습니다.
db.users.update({_id:123}, {$set:{
"friends.$[updateFriend].emails.$[updateEmail].email" : "lucy.is.gucy@zmail.com"
}}, {
"arrayFilters": [
{"updateFriend.name" : "lucy"},
{"updateEmail.email" : "lucyGucy@zmail.com"}
]
})
이렇게 하면 업데이트는 특정 어레이 순서에 영향을 받지 않습니다.위의 예에서는 어레이 필터 기준을 충족하는 모든 요소(어레이에도 적용됨)와 일치하는 두 가지 식별자 updateFriend와 updateEmail을 사용하고 있습니다.매뉴얼에 기재되어 있는 바와 같이:
<identifier>는 소문자로 시작하고 영숫자만 포함해야 합니다.
또한 이메일은 고유할 수 있지만 arrayFilters가 정확할 수 있도록 모든 서브 문서에 고유 ID를 포함할 것을 권장합니다.
Mongoose를 사용한 솔루션:
Users.findById("123", function(err, user) {
var friends = user.friends;
for ( i=0; i < friends.length; i++ ) {
if (friends[i].name == 'allen') {
friends[i].email = '2222';
user.save(function(err) {
if (err) throw err;
console.log("email updated");
});
} else {
console.log("no friends named allen");
}
}
}
멀티레벨 arry의 갱신은 정말 귀찮습니다.내 방식대로라면, 깊은 레벨의 arry를 교환해 주세요.
db.user.findOne({_id:'123'},{friends:1}).lean().exec(function(err,user){
var whichArrayToUpdate;
for (var ii = 0; ii < user.friends.length; ii++) {
for (var jj = 0; i < user.friends[ii].emails; jj++) {
if(user.friends[ii].emails[jj].email == '1111' ){// update it below
user.friends[ii].emails[jj].email == 'what ever you want to set to.';
whichArrayToReplace = user.friends[ii].emails;
break;
}
};
};
db.user.update({'friends.name':'allen'},{$set{'friends.$.email': whichArrayToReplace} })
})
그런데 왜 save() 메서드를 사용하지 않습니까?save()는 문서 전체를 대신합니다.문서가 작다면 괜찮습니다만, 문서가 크다면 문서의 일부만 교체하는 것이 좋습니다.
또는 루프를 실행하여 탑 레벨 어레이와 세컨드 레벨 어레이(ii 및 jj)의 위치를 사용하여 업데이트합니다.
스키마를 설계할 때는 어레이 업데이트를 하지 않는 한 어레이를 다른 어레이에 배치하지 마십시오.
다음과 같은 주요 카테고리가 있는 유사한 상황이 있습니다.
{
"service": {
"isReviewed": false,
"_id": "5ea36b27d7ae560845afb88d",
"mainCategory": "message ",
"SubCategory": [
{
"priceChanged": true,
"_id": "5ea36b27d7ae560845afb88e",
"subCatPrice": "26",
"subCatName": "mustach trimming"
}
],
"shopName": "paddy the barber",
"user": "5ea1fd5b69512dc72ad2f48c",
"date_created": "2020-04-24T22:41:43.368Z",
"__v": 5
}
}
이제 하위 문서는 개체로 저장되므로 하위 문서의 일부를 업데이트하는 방법을 찾는 데 시간이 걸렸습니다.
All id는 put/:id를 통과할 때 먼저 문서의 _id를 확인합니다.그리고 문서 소유자와 req.user를 대조했습니다.
모든 것이 괜찮다면, 저는 어레이를 루프하고 나서 새로운 객체를 만들었습니다.그리고 각각의 바디에서 가격이나 이름을 확인하고 새로운 가격이 있다면 오브젝트의 가격 값을 갱신하는 것 뿐입니다.새 값이 있는 경우 개체는 그대로 유지됩니다.
내가 말한 건 서비스야SubCategory = newObject 및 데이터 저장.
정상적으로 동작하고 있습니다만, subdoc_id가 갱신되는 문제에 부딪혔기 때문에 이전 값을 그대로 유지하여 수정했습니다.
퍼포먼스와 최적화에 관해서는 이것이 올바른 방법인지 아닌지는 잘 모르겠습니다.또, 만약 그것이 잘 기능하고 있다면, 저는 기꺼이 바꿀 수 있습니다.
코드는 다음과 같습니다.
const newObject = {
subCatPrice: "",
subCatName: "",
_id: "",
priceChanged: false
};
let oldDetails = service.SubCategory;
for (const old of oldDetails) {
newObject.subCatPrice = old.subCatPrice;
newObject.subCatName = old.subCatName;
newObject._id = old._id;
}
price ? (newObject.subCatPrice = price ) && (newObject.priceChanged = true) : newObject.subCatPrice;
name ? (newObject.subCatName = name) : newObject.subCatName;
(service.SubCategory = newObject), await service.save();
저는 솔직히 상태의 리액션 아이디어를 이용했습니다.개체의 복사본을 가져와 보관하고 갱신하고 싶은 부분에 업데이트를 적용합니다.
클린 코드나 그 모든 것에 관해서는, 이것이 올바른 방법인지 아닌지는 잘 모르겠습니다만, 저도 프로그래밍의 학생이기 때문에, 배우고 싶습니다.
이게 도움이 됐으면 좋겠는데
언급URL : https://stackoverflow.com/questions/19603542/how-can-i-update-a-property-of-an-object-that-is-contained-in-an-array-of-a-pare
'programing' 카테고리의 다른 글
JSON 스키마에서 스키마를 확장하는 방법 (0) | 2023.03.27 |
---|---|
React.js의 정상적인 디버깅 튜토리얼 (0) | 2023.03.27 |
.NET Core: API JSON 응답에서 null 필드를 삭제합니다. (0) | 2023.03.22 |
mapStateToProps 대신 useselector/useDispatch를 사용해야 합니까? (0) | 2023.03.22 |
ORA-01882: 시간대 영역을 찾을 수 없습니다. (0) | 2023.03.22 |