복붙노트

[MONGODB] 어떻게 새 개체는 기존에 / 병합을 오버레이 있도록 내가 부분적으로 MongoDB를에서 개체를 업데이트 할

MONGODB

어떻게 새 개체는 기존에 / 병합을 오버레이 있도록 내가 부분적으로 MongoDB를에서 개체를 업데이트 할

MongoDB에 저장이 문서를 감안할 때

{
   _id : ...,
   some_key: { 
        param1 : "val1",
        param2 : "val2",
        param3 : "val3"
   }
}

외부 세계에서 PARAM2 및 3 당겨에 새로운 정보를 가진 객체가 저장 될 필요가

var new_info = {
    param2 : "val2_new",
    param3 : "val3_new"
};

그 PARAM1이 제거되지 않습니다 그래서 나는 / 병합 개체의 기존 상태를 통해 새로운 분야를 오버레이 할

이렇게이

db.collection.update(  { _id:...} , { $set: { some_key : new_info  } } 

MongoDB를 초래할 것인가가 질문을 받았다 그대로하고있다, 그리고 세트는 그 값으로 some_key. 예전 교체.

{
   _id : ...,
   some_key: { 
      param2 : "val2_new",
      param3 : "val3_new"
   }
}

(그들에게 한 명시 적으로 하나를 명시하지 않고) MongoDB를 업데이트에만 새 필드를 가지고 할 수있는 방법은 무엇입니까? 내용 :

{
   _id : ...,
   some_key: { 
        param1 : "val1",
        param2 : "val2_new",
        param3 : "val3_new"
   }
}

나는 자바 클라이언트를 사용하고 있지만, 어떤 예를 부탁드립니다

해결법

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

    1.내가 제대로 질문을 이해한다면, 당신은 (심지어 다른 값을 경우) 다른 문서의 내용을하지만, 이미 존재하지 않는 필드 만있는 문서를 업데이트하고, 완전히 이미 설정되어있는 필드를 무시해야합니다.

    내가 제대로 질문을 이해한다면, 당신은 (심지어 다른 값을 경우) 다른 문서의 내용을하지만, 이미 존재하지 않는 필드 만있는 문서를 업데이트하고, 완전히 이미 설정되어있는 필드를 무시해야합니다.

    하나의 명령에 그렇게 할 수있는 방법은 없습니다.

    당신은 당신이 $ 설정할 무엇을 첫 번째 문서, 그림을 조회하고 (당신이 사이에 동시 업데이트를하지 않을 수 있도록 일치하는 필터로 이전 값을 사용)를 업데이트해야합니다.

    질문의 또 다른 읽기는 $ 세트에 만족하지만, 명시 적으로 모든 필드를 설정하지 않는 것입니다. 당신은 어떻게 다음 데이터를 전달할 것인가?

    당신은 당신이 다음을 수행 할 수 있습니다 알고 :

    db.collection.update(  { _id:...} , { $set: someObjectWithNewData } 
    
  2. ==============================

    2.난 내 자신의 기능을 해결했다. 당신이 문서에 지정된 필드를 업데이트 할 경우에 당신은 명확하게 해결해야합니다.

    난 내 자신의 기능을 해결했다. 당신이 문서에 지정된 필드를 업데이트 할 경우에 당신은 명확하게 해결해야합니다.

    예:

    {
        _id : ...,
        some_key: { 
            param1 : "val1",
            param2 : "val2",
            param3 : "val3"
        }
    }
    

    만 PARAM2를 업데이트 할 경우 어떻게 잘못 :

    db.collection.update(  { _id:...} , { $set: { some_key : new_info  } }  //WRONG
    

    당신은 사용해야합니다 :

    db.collection.update(  { _id:...} , { $set: { some_key.param2 : new_info  } } 
    

    그래서 난 그런 기능 무언가를 썼다 :

    function _update($id, $data, $options=array()){
    
        $temp = array();
        foreach($data as $key => $value)
        {
            $temp["some_key.".$key] = $value;
        } 
    
        $collection->update(
            array('_id' => $id),
            array('$set' => $temp)
        );
    
    }
    
    _update('1', array('param2' => 'some data'));
    
  3. ==============================

    3.당신은 깊은 물체 내부의 해당 개체의 다른 속성에 영향을주지 않고 액세스 및 세트 필드 점 표기법을 사용할 수 있습니다.

    당신은 깊은 물체 내부의 해당 개체의 다른 속성에 영향을주지 않고 액세스 및 세트 필드 점 표기법을 사용할 수 있습니다.

    당신이 위에서 지정한 객체 감안할 때 :

    > db.test.insert({"id": "test_object", "some_key": {"param1": "val1", "param2": "val2", "param3": "val3"}})
    WriteResult({ "nInserted" : 1 })
    

    우리는 단지 some_key.param2 및 some_key.param3를 업데이트 할 수 있습니다 :

    > db.test.findAndModify({
    ... query: {"id": "test_object"},
    ... update: {"$set": {"some_key.param2": "val2_new", "some_key.param3": "val3_new"}},
    ... new: true
    ... })
    {
        "_id" : ObjectId("56476e04e5f19d86ece5b81d"),
        "id" : "test_object",
        "some_key" : {
            "param1" : "val1",
            "param2" : "val2_new",
            "param3" : "val3_new"
        }
    }
    

    당신은 당신 같은 깊이로 탐구 할 수 있습니다. 이것은 또한 기존에 영향을주지 않고 객체에 새 속성을 추가하는 데 유용합니다.

  4. ==============================

    4.가장 좋은 방법은 개체에서 속성을 추출하고 그들에게 평면 점 표기법 키 - 값 쌍을 만드는 것입니다. 당신은 예를 들어이 라이브러리에 사용할 수 있습니다 :

    가장 좋은 방법은 개체에서 속성을 추출하고 그들에게 평면 점 표기법 키 - 값 쌍을 만드는 것입니다. 당신은 예를 들어이 라이브러리에 사용할 수 있습니다 :

    https://www.npmjs.com/package/mongo-dot-notation

    그것은 기존의 DB 객체의 모든 속성이 필요없이 삭제 / 덮어 될 것이라고 걱정없이 당신이 다음 $ 설정 수정에 제공 될 수있는 성질의 평면 집합으로 개체를 변경할 수 있습니다 .flatten 기능을 가지고 있습니다.

    몽고 점 표기법의 문서에서 발췌 :

    var person = {
      firstName: 'John',
      lastName: 'Doe',
      address: {
        city: 'NY',
        street: 'Eighth Avenu',
        number: 123
      }
    };
    
    
    
    var instructions = dot.flatten(person)
    console.log(instructions);
    /* 
    {
      $set: {
        'firstName': 'John',
        'lastName': 'Doe',
        'address.city': 'NY',
        'address.street': 'Eighth Avenu',
        'address.number': 123
      }
    }
    */
    

    그리고 그것은 완벽한 선택기를 형성 - 그것은 단지 주어진 속성을 업데이트합니다. 편집 : 나는 몇 번 고고학자로 좋아)

  5. ==============================

    5.몽고 당신은을 사용하여 중첩 된 문서를 업데이트 할 수 있습니다. 협약. 보세요 : MongoDB의 중첩 된 문서를 업데이트. 생각 당신은 내가 찾고있는 것 같이 여기에 병합 업데이트에 대한 과거의 또 다른 문제는,이다 : MongoDB를 원자 업데이트는 '병합'문서를 통해

    몽고 당신은을 사용하여 중첩 된 문서를 업데이트 할 수 있습니다. 협약. 보세요 : MongoDB의 중첩 된 문서를 업데이트. 생각 당신은 내가 찾고있는 것 같이 여기에 병합 업데이트에 대한 과거의 또 다른 문제는,이다 : MongoDB를 원자 업데이트는 '병합'문서를 통해

  6. ==============================

    6.나는 이런 식으로 일을 성공했다 :

    나는 이런 식으로 일을 성공했다 :

    db.collection.update(  { _id:...} , { $set: { 'key.another_key' : new_info  } } );
    

    내 프로필 업데이트를 동적으로 처리하는 기능을 가지고

    function update(prop, newVal) {
      const str = `profile.${prop}`;
      db.collection.update( { _id:...}, { $set: { [str]: newVal } } );
    }
    

    참고 : '프로파일'당신이 수정하고자하는 키의 단지 문자열입니다, 내 구현 고유의 것입니다.

  7. ==============================

    7.당신은 당신이 원하는 것을 성취 할 수있는 isPartialObject을 설정할 수 있습니다 것 같습니다.

    당신은 당신이 원하는 것을 성취 할 수있는 isPartialObject을 설정할 수 있습니다 것 같습니다.

  8. ==============================

    8.

        // where clause DBObject
        DBObject query = new BasicDBObject("_id", new ObjectId(id));
    
        // modifications to be applied
        DBObject update = new BasicDBObject();
    
        // set new values
        update.put("$set", new BasicDBObject("param2","value2"));
    
       // update the document
        collection.update(query, update, true, false); //3rd param->upsertFlag, 4th param->updateMultiFlag
    

    여러 필드가있는 경우 업데이트 할

            Document doc = new Document();
            doc.put("param2","value2");
            doc.put("param3","value3");
            update.put("$set", doc);
    
  9. ==============================

    9.네, 가장 좋은 방법은이 댓글에서 언급 한 바와 같이, 평면 키 - 값의 문자열 표현으로 객체 표기법을 변환하는 것입니다 : https://stackoverflow.com/a/39357531/2529199

    네, 가장 좋은 방법은이 댓글에서 언급 한 바와 같이, 평면 키 - 값의 문자열 표현으로 객체 표기법을 변환하는 것입니다 : https://stackoverflow.com/a/39357531/2529199

    https://www.npmjs.com/package/dot-object는 점 표기법을 사용하여 다른 개체를 조작 할 수 있습니다 :이 NPM 라이브러리를 사용하는 다른 방법을 강조하고 싶었다.

    다음 I는, 프로그램 기능 변수로 키 값을 수락 중첩 객체 속성을 생성하기 위해 패턴을 사용했을

    const dot = require('dot-object');
    
    function(docid, varname, varvalue){
      let doc = dot.dot({
          [varname]: varvalue 
      });
    
      Mongo.update({_id:docid},{$set:doc});
    }
    

    이 패턴은 저를 상호 교환 단일 레벨 속성뿐만 아니라 중첩, 그리고 몽고에 완전히 삽입 해 사용할 수 있습니다.

    몽고 작업 할 때 JS 특히 클라이언트 측에, 단지 몽고 이상의 개체 함께 놀러 필요하지만 일관성이있는 경우,이 라이브러리는 당신에게 앞서 언급 한 몽고 점 표기법의 NPM 모듈보다 더 많은 옵션을 제공합니다.

    내가 원래 싶었 P.S은 주석으로이 문제를 언급하지만 분명히 내 S / O 담당자는 댓글을 게시 할 수있을만큼 충분히 높은 아니다. 그래서, 그냥 다른 모듈을 제공 강조하고 싶었 SzybkiSasza의 의견에 근육에 노력하지.

  10. ==============================

    10.이 과정을 $ 세트를 사용

    이 과정을 $ 세트를 사용

    .update({"_id": args.dashboardId, "viewData._id": widgetId}, {$set: {"viewData.$.widgetData": widgetDoc.widgetData}})
    .exec()
    .then(dashboardDoc => {
        return {
            result: dashboardDoc
        };
    }); 
    
  11. ==============================

    11.필요한 점 경로를 포함한 속성 이름과 업데이트 개체를 확인합니다. (OP의 예에서 "somekey."+), 및 업데이트를 수행 한 후 사용.

    필요한 점 경로를 포함한 속성 이름과 업데이트 개체를 확인합니다. (OP의 예에서 "somekey."+), 및 업데이트를 수행 한 후 사용.

    //the modification that's requested
    updateReq = { 
       param2 : "val2_new",
       param3 : "val3_new"   
    }
    
    //build a renamed version of the update request
    var update = {};
    for(var field in updateReq){
        update["somekey."+field] = updateReq[field];
    }
    
    //apply the update without modifying fields not originally in the update
    db.collection.update({._id:...},{$set:update},{upsert:true},function(err,result){...});
    
  12. ==============================

    12.나는 기존의 객체의 특정 필드를 업데이트 할 findAndModify ()을 시도했다.

    나는 기존의 객체의 특정 필드를 업데이트 할 findAndModify ()을 시도했다.

    https://docs.mongodb.com/manual/reference/method/db.collection.findAndModify/

  13. ==============================

    13.몽고 4.2 시작, db.collection.update는 ()와 같은 입력 문서 및 새로 추가 된 필드에서 기존의 모든 필드를 출력 $ addFields, 같은 집계 연산자를 사용하여 수있는 통합 파이프 라인을 받아 들일 수 있습니다 :

    몽고 4.2 시작, db.collection.update는 ()와 같은 입력 문서 및 새로 추가 된 필드에서 기존의 모든 필드를 출력 $ addFields, 같은 집계 연산자를 사용하여 수있는 통합 파이프 라인을 받아 들일 수 있습니다 :

    var new_info = { param2: "val2_new", param3: "val3_new" }
    
    // { some_key: { param1: "val1", param2: "val2", param3: "val3" } }
    // { some_key: { param1: "val1", param2: "val2"                 } }
    db.collection.update({}, [{ $addFields: { some_key: new_info } }], { multi: true })
    // { some_key: { param1: "val1", param2: "val2_new", param3: "val3_new" } }
    // { some_key: { param1: "val1", param2: "val2_new", param3: "val3_new" } }
    
  14. ==============================

    14.당신은 상호 교환 객체를 업데이트하고 단순히 업데이트 된 필드 개체를 저장에 대해 생각해야한다. 아래 다 같은 뭔가

    당신은 상호 교환 객체를 업데이트하고 단순히 업데이트 된 필드 개체를 저장에 대해 생각해야한다. 아래 다 같은 뭔가

    function update(_id) {
        return new Promise((resolve, reject) => {
    
            ObjModel.findOne({_id}).exec((err, obj) => {
    
                if(err) return reject(err)
    
                obj = updateObject(obj, { 
                    some_key: {
                        param2 : "val2_new",
                        param3 : "val3_new"
                    }
                })
    
                obj.save((err, obj) => {
                    if(err) return reject(err)
                    resolve(obj)
                })
            })
        })
    }
    
    
    function updateObject(obj, data) {
    
        let keys = Object.keys(data)
    
        keys.forEach(key => {
    
            if(!obj[key]) obj[key] = data[key]
    
            if(typeof data[key] == 'object') 
                obj[key] = updateObject(obj[key], data[key])
            else
                obj[key] = data[key]
        })
    
        return obj
    }
    
  15. ==============================

    15.

    db.collection.update(  { _id:...} , { $set: { some_key : new_info  } } 
    

    db.collection.update( { _id: ..} , { $set: { some_key: { param1: newValue} } } ); 
    

    이 도움말을 희망!

  16. ==============================

    16.몽고 3.6에서 정확하게 당신이 필요하고 함수 mergeObjects 있습니다 :

    몽고 3.6에서 정확하게 당신이 필요하고 함수 mergeObjects 있습니다 :

    https://docs.mongodb.com/manual/reference/operator/aggregation/mergeObjects/

  17. from https://stackoverflow.com/questions/10290621/how-do-i-partially-update-an-object-in-mongodb-so-the-new-object-will-overlay by cc-by-sa and MIT license