给定此文档保存在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客户端,但是任何示例都将受到欢迎
从Mongo 4.2开始,db.collection.updateMany()(或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.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" } }
The first part {} is the match query, filtering which documents to update (in this case all documents).
The second part [{ $addFields: { some_key: new_info } }] is the update aggregation pipeline:
Note the squared brackets signifying the use of an aggregation pipeline.
Since this is an aggregation pipeline, we can use $addFields.
$addFields performs exactly what you need: updating the object so that the new object will overlay / merge with the existing one:
In this case, { param2: "val2_new", param3: "val3_new" } will be merged into the existing some_key by keeping param1 untouched and either add or replace both param2 and param3.
// 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);