如何在MongoDB中部分更新对象,使新对象与现有对象叠加/合并?

5 浏览
0 Comments

如何在MongoDB中部分更新对象,使新对象与现有对象叠加/合并?

给定存储在MongoDB中的文档

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

来自外部世界的包含关于param2param3的新信息的对象需要保存

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客户端,但会欣赏任何示例

admin 更改状态以发布 2023年5月22日
0
0 Comments

如果我理解问题正确,您想使用另一个文档的内容更新文档,但仅更新不存在的字段,完全忽略已经设置(即使为另一个值)的字段。然而,在单一的命令中不能完成这个操作。\n\n您必须先查询文档,确定您要更新的字段,然后更新它(使用旧值作为匹配过滤器以确保您不会在其中获得并发更新)。\n\n


\n另一种解读您的问题的方式是您对 $set 感到满意,但不想明确设置所有字段。那么如何传递数据呢?\n\n您知道可以执行以下操作:\n\n

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

0
0 Comments

我用自己的函数解决了它。如果你想要更新文档中的指定字段,需要明确地解决它。

举个例子:

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

0