복붙노트

[MONGODB] MongoDB를 갱신 어레이의 다수의 레코드 [중복]

MONGODB

MongoDB를 갱신 어레이의 다수의 레코드 [중복]

나는 최근에 MongoDB를 사용하기 시작하고 나는 문서의 배열을 업데이트에 관한 질문이 있습니다. 나는이 같은 구조를 가지고 :

{
"_id" : ObjectId(),
"post" : "",
"comments" : [
        {
                "user" : "test",
                "avatar" : "/static/avatars/asd.jpg",
                "text" : "....."
        }
        {
                "user" : "test",
                "avatar" : "/static/avatars/asd.jpg",
                "text" : "....."
        }
        {
                "user" : "test",
                "avatar" : "/static/avatars/asd.jpg",
                "text" : "....."
        }
        ...
   ]
}

나는 다음과 같은 쿼리를 실행하기 위해 노력하고있어 :

update({"comments.user":"test"},{$set:{"comments.$.avatar": "new_avatar.jpg"}},false,true)

문제는 모든 문서를 업데이트하지만 모든 문서의 첫 번째 배열 요소를 업데이트 할 것입니다. 모든 배열 요소 또는 내가 수동으로 수행하려고한다을 업데이트하는 방법은 없나요? 감사.

해결법

  1. ==============================

    1.단일 업데이트 작업에 여러 개의 배열 요소를 수정할 수 없습니다. 따라서, 당신은 수정 될 여러 배열 요소를 필요로 마이그레이션 문서를 위해 업데이트를 반복해야합니다. 당신은 문서가 관련 의견을 모두 가질 때까지 대체 반복 예컨대, $ elemMatch과 업데이트를 적용 컬렉션의 각 문서를 반복하여이 작업을 수행 할 수 있습니다 :

    단일 업데이트 작업에 여러 개의 배열 요소를 수정할 수 없습니다. 따라서, 당신은 수정 될 여러 배열 요소를 필요로 마이그레이션 문서를 위해 업데이트를 반복해야합니다. 당신은 문서가 관련 의견을 모두 가질 때까지 대체 반복 예컨대, $ elemMatch과 업데이트를 적용 컬렉션의 각 문서를 반복하여이 작업을 수행 할 수 있습니다 :

    db.collection.find().forEach( function(doc) {
      do {
        db.collection.update({_id: doc._id,
                              comments:{$elemMatch:{user:"test",
                                                    avatar:{$ne:"new_avatar.jpg"}}}},
                             {$set:{"comments.$.avatar":"new_avatar.jpg"}});
      } while (db.getPrevError().n != 0);
    })
    

    이 작업의 효율성이 응용 프로그램에 대한 요구 사항 인 경우, 당신은 사용자의 아바타의 위치가 아니라 모든 의견보다, 하나의 문서에 저장되는 스키마는 정상화해야합니다.

  2. ==============================

    2.한 가지 해결책은 foreach는 함께 사용할 수있는 기능을 생성하고 (신속 실행되도록)을 evaling 수 있습니다. 컬렉션을 가정하면 "기사"입니다, 다음을 실행할 수 있습니다 :

    한 가지 해결책은 foreach는 함께 사용할 수있는 기능을 생성하고 (신속 실행되도록)을 evaling 수 있습니다. 컬렉션을 가정하면 "기사"입니다, 다음을 실행할 수 있습니다 :

    var runUpdate = function(){
        db.article.find({"comments.user":"test").forEach( function(article) {
            for(var i in article.comments){
                article.comments[i].avatar = 'new_avatar.jpg';
            }
            db.article.save(article);
        });
    };
    
    db.eval(runUpdate);
    
  3. ==============================

    3.당신이 인덱스를 알고 있다면 당신은이 같은 문제없이 수행 할 수 있습니다 업데이트 할 :

    당신이 인덱스를 알고 있다면 당신은이 같은 문제없이 수행 할 수 있습니다 업데이트 할 :

    var update = { $set: {} };
    for (var i = 0; i < indexesToUpdate.length; ++i) {
      update.$set[`comments.${indexesToUpdate[i]}. avatar`] = "new_avatar.jpg";
    }
    Comments.update({ "comments.user":"test" }, update, function(error) {
      // ...
    });
    
  4. ==============================

    4.당신이 할 수있는 것 같다 :

    당신이 할 수있는 것 같다 :

    db.yourCollection.update({"comments.user":"test"},{$set:{"comments.0.avatar": "new_avatar.jpg", "comments.1.avatar": "new_avatar.jpg", etc...})
    

    당신은 배열 요소의 작은 알려진 번호가있는 경우 그래서,이 할 수있는 좀 더 쉽게 할 수 있습니다. 당신이 뭔가하려는 경우 "의견을 * 아바타.."- 그렇게하지 않도록하는 방법. 그것은 당신이 너무 많은 데이터 중복 상점을 가지고 아마 잘되지 않습니다 ..

  5. from https://stackoverflow.com/questions/14720734/mongodb-update-multiple-records-of-array by cc-by-sa and MIT license