code

새 개체가 기존 개체와 오버레이/마지되도록 MongoDB 개체를 부분적으로 업데이트하려면 어떻게 해야 합니까?

starcafe 2023. 2. 16. 21:56
반응형

새 개체가 기존 개체와 오버레이/마지되도록 MongoDB 개체를 부분적으로 업데이트하려면 어떻게 해야 합니까?

이 문서가 MongoDB에 저장되어 있는 경우

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

에 대한 새로운 를 가진 param2 ★★★★★★★★★★★★★★★★★」param3

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가 (1개씩 명시적으로 기술하지 않고) 새로운 필드만 업데이트하도록 하는 방법은 무엇입니까?입수 방법:

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

자바 클라이언트를 사용하고 있습니다만, 어떤 예라도 감사하게 생각합니다.

나는 내 기능으로 그것을 해결했다.문서에서 지정된 필드를 업데이트하려면 해당 필드를 명확하게 지정해야 합니다.

예:

{
    _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'));

질문을 올바르게 이해한 경우, 다른 문서의 내용으로 문서를 업데이트하고, 아직 존재하지 않는 필드만 업데이트하고, 이미 설정된 필드는 완전히 무시합니다(다른 값으로 변경되더라도).

한 번의 명령으로 그것을 수행할 수 있는 방법은 없습니다.

를 먼저.$set그런 다음 업데이트(이전 값을 일치 필터로 사용하여 중간에 동시 업데이트를 받지 않도록 함)합니다.


의 또 다른 은 여러분이 입니다.$set.그럼 데이터를 어떻게 전달하시겠습니까?

다음 작업을 수행할 수 있습니다.

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

도트 표시를 사용하면 오브젝트의 다른 속성에 영향을 주지 않고 오브젝트 깊은 곳에 있는 필드에 액세스하여 설정할 수 있습니다.

위에서 지정한 오브젝트 지정:

> 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"
    }
}

원하는 만큼 깊이 파헤쳐도 돼또한 기존 속성에 영향을 주지 않고 개체에 새 속성을 추가하는 경우에도 유용합니다.

최적의 솔루션은 객체에서 속성을 추출하여 플랫 도트-표기 키-값 쌍을 만드는 것입니다.예를 들어 이 라이브러리를 사용할 수 있습니다.

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

말말 it it it it 가 있다..flatten이 함수는 기존 DB 객체의 속성이 불필요하게 삭제/덮어쓰기될 염려 없이 객체를 $set 수식자에 지정할 수 있는 평평한 속성 세트로 변경할 수 있도록 합니다.

mongo-dot-notation 삭제:

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
  }
}
*/

그런 다음 완벽한 선택기를 형성합니다. 지정된 속성만 업데이트됩니다.편집: 저는 가끔 고고학자가 되고 싶습니다;)

작작으로 Mongo 4.2, (또는 )는 집약 파이프라인을 받아들일 수 있습니다.이를 통해 입력 문서 및 새로 추가된 필드에서 기존의 모든 필드를 출력하는 등의 집약 연산자를 사용할 수 있습니다.

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.updateMany({}, [{ $addFields: { some_key: new_info } }])
// { some_key: { param1: "val1", param2: "val2_new", param3: "val3_new" } }
// { some_key: { param1: "val1", param2: "val2_new", param3: "val3_new" } }
  • 은요.{}는 갱신할 문서(이 경우 모든 문서)를 필터링하는 일치 쿼리입니다.

  • 파트, 두 번째 파트입니다.[{ $addFields: { some_key: new_info } }]파이프라인입니다.

    • 집약 파이프라인의 사용을 나타내는 각 괄호에 주의해 주세요.
    • 이것은 집약 파이프라인이기 때문에 를 사용할 수 있습니다.
    • $addFields합니다.새로운 오브젝트가 기존 오브젝트와 오버레이/마지되도록 오브젝트를 갱신합니다.
    • 「」는,{ param2: "val2_new", param3: "val3_new" } 기 will will will will the the the the the the 에 병합됩니다.some_keyparam1 않고 둘 다 합니다.param2 ★★★★★★★★★★★★★★★★★」param3.

하면 Mongo를 할 수 ..관습.다음 항목을 참조하십시오.mongodb에서 중첩된 문서를 업데이트하는 입니다.MongoDB atomic update by 'merge' document와 같은 과거 머지 업데이트에 대한 질문이 있습니다.

저는 이 방법으로 성공했습니다.

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 } } );
}

주의: 'profile'은 구현에 고유하며 수정하는 키 문자열입니다.

업서트를 하는 것이 좋습니다.MongoDB의 이 조작은 문서를 컬렉션에 저장하는 데 사용됩니다.문서가 질의 조건과 일치하면 업데이트 작업을 수행합니다. 그렇지 않으면 새 문서를 모음에 삽입합니다.

다음과 같은 것

db.employees.update(
    {type:"FT"},
    {$set:{salary:200000}},
    {upsert : true}
 )

하시면 됩니다.$mergeObjects에그리게이션 베이스의 갱신으로 합니다. 같은 거

db.collection.update(
   { _id:...},
   [{"$set":{
      "some_key":{
        "$mergeObjects":[
          "$some_key",
          new info or { param2 : "val2_new", param3 : "val3_new"}
       ]
      }
   }}]
)

기타 예

    // 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);

원하는 것을 달성할 수 있는 isPartialObject를 설정할 수 있을 것 같습니다.

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

로.

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

도움이 되었으면 좋겠다!

Embedded Documents(경로 객체 문자열)를 사용해야 합니다.

let update = {}
Object.getOwnPropertyNames(new_info).forEach(param => {
   update['some_key.' + param] = new_info[param]
})

따라서 JavaScript에서는 Spread Operator(...)를 사용하여 업데이트할 수 있습니다.

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

네, 가장 좋은 방법은 오브젝트 표기법을 플랫키 값 문자열 표현으로 변환하는 것입니다.https://stackoverflow.com/a/39357531/2529199

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

키 값을 함수 변수로 받아들일 때 이 패턴을 사용하여 다음과 같이 중첩된 개체 속성을 프로그래밍적으로 만들었습니다.

const dot = require('dot-object');

function(docid, varname, varvalue){
  let doc = dot.dot({
      [varname]: varvalue 
  });

  Mongo.update({_id:docid},{$set:doc});
}

이 패턴은 네스트된 특성과 싱글 레벨 속성을 서로 바꿔 사용할 수 있도록 하여 몽고에 깔끔하게 삽입할 수 있도록 합니다.

Mongo뿐만 아니라 클라이언트 측에서도 JS오브젝트를 가지고 놀아야 하지만 Mongo를 사용할 때 일관성이 있다면 이 라이브러리는 앞서 말한 것보다 더 많은 옵션을 제공합니다.mongo-dot-notationNPM 모듈

P.S 저는 원래 이 말을 댓글로 하고 싶었지만, 제 S/O 담당자는 댓글을 달 만큼 높지 않은 것 같습니다.그래서 SzybkiSasza의 코멘트에 억지로 끼어들려는 것이 아니라 대체 모듈을 제공하는 것을 강조하고 싶었다.

나는 노력했다.findAndModify()기존 객체의 특정 필드를 업데이트합니다.

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

$set을 사용하여 이 프로세스를 수행합니다.

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

필요한 도트 경로를 포함한 속성 이름으로 업데이트 개체를 만든 다음("OP 예제의 "+") 업데이트를 수행하는 데 사용합니다.

//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){...});

개체를 서로 바꿔서 업데이트하는 방법을 생각해 보고 업데이트된 필드와 함께 개체를 저장해야 합니다.다음과 같은 작업을 수행

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
}

오브젝트의 여러 필드를 갱신하는 경우는, 다음의 조작을 실행할 수 있습니다.

 let fieldsToUpdate = {};
 for (const key in allFields) {
 const fieldName = `flags.${key}`;   // define field as string literal
     fieldsToUpdate[fieldName] = allFields[key];
 }
 db.collection.updateOne(query, { $set: { ...fieldsToUpdate } } );

언급URL : https://stackoverflow.com/questions/10290621/how-do-i-partially-update-an-object-in-mongodb-so-the-new-object-will-overlay

반응형