이 문서가 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가 새 필드 만 명시 적으로 업데이트하지 않는 방법은 무엇입니까? 이것을 얻으려면 :
{
_id : ...,
some_key: {
param1 : "val1",
param2 : "val2_new",
param3 : "val3_new"
}
}
Java 클라이언트를 사용하고 있지만 모든 예를 들어 주시면 감사하겠습니다.
답변
질문을 올바르게 이해하면 다른 문서의 내용으로 문서를 업데이트하고 아직 존재하지 않는 필드 만 업데이트하고 이미 설정된 필드 (다른 값이더라도)를 완전히 무시하려고합니다.
단일 명령으로는 그렇게 할 수 없습니다.
먼저 문서를 쿼리하고 원하는 것을 $set
파악한 다음 업데이트해야합니다 (이전 값을 일치하는 필터로 사용하여 사이에 동시 업데이트를받지 않도록해야합니다).
귀하의 질문에 대한 또 다른 독서는 당신이 만족 $set
하지만 모든 필드를 명시 적으로 설정하고 싶지 않다는 것입니다. 그러면 데이터를 어떻게 전달 하시겠습니까?
다음을 수행 할 수 있다는 것을 알고 있습니다.
db.collection.update( { _id:...} , { $set: someObjectWithNewData }
답변
나는 내 자신의 기능으로 그것을 해결했다. 문서에서 지정된 필드를 업데이트하려면 명확하게 해결해야합니다.
예:
{
_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'));
답변
점 표기법을 사용하여 객체의 다른 속성에 영향을주지 않고 객체 내부의 필드에 액세스하고 설정할 수 있습니다.
위에서 지정한 객체가 주어지면 :
> 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
그것은이 .flatten
필요없이 기존 DB 객체의 속성이 될 것이라고 우려 삭제 / 덮어 쓰기하지 않고, 당신이 다음 $ 설정 수정에 제공 될 수있는 성질의 평면 집합으로 개체를 변경할 수있는 기능.
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를 사용하면 .
규칙을 사용하여 중첩 문서를 업데이트 할 수 있습니다 . 보세요 : MongoDB의 중첩 된 문서를 업데이트 . 다음은 내가 생각하는 것과 같은 병합 업데이트에 대한 과거의 또 다른 질문입니다. ‘병합’문서를 통한 MongoDB 원자 업데이트
답변
나는 이런 식으로 성공했다 :
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’은 구현에 따라 다르며 수정하려는 키 문자열입니다.