programing

mongodb를 사용하여 부모 객체의 배열에 포함된 객체의 속성을 업데이트하려면 어떻게 해야 합니까?

linuxpc 2023. 3. 22. 20:49
반응형

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

반응형