概述
MongoDB 是一款开源的文档型NoSQL数据库。我们可以通过 update
、replace
和 save
等方法更新集合中的文档。要修改文档中的特定字段,需要使用 $set
、$inc
等操作符。
本文将深入探讨如何使用 update
和 replace
查询修改文档的多个字段。我们先从MongoDB Shell查询入手,再对应实现Java代码。
使用Shell查询更新不同字段
首先创建测试数据库 baeldung
和集合 employee
:
use baeldung;
db.createCollection(employee);
插入测试数据:
db.employee.insertMany([
{
"employee_id": 794875,
"employee_name": "David Smith",
"job": "Sales Representative",
"department_id": 2,
"salary": 20000,
"hire_date": NumberLong("1643969311817")
},
{
"employee_id": 794876,
"employee_name": "Joe Butler",
"job": "Sales Manager",
"department_id": 3,
"salary": 30000,
"hire_date": NumberLong("1645338658000")
}
]);
更新单个文档的多个字段
使用 $set
和 $inc
操作符组合更新:
$set
:直接设置新值$inc
:对数值字段进行增量修改
db.employee.updateOne(
{
"employee_id": 794875,
"employee_name": "David Smith"
},
{
$set:{
department_id:3,
job:"Sales Manager"
}
}
);
混合使用操作符的示例:
db.employee.updateOne(
{
"employee_id": 794875
},
{
$inc: {
department_id: 1
},
$set: {
job: "Sales Manager"
}
}
);
更新多个文档的多个字段
批量更新需要添加 multi: true
选项(或使用 updateMany
):
db.employee.update(
{
"job": "Sales Representative"
},
{
$inc: {
salary: 10000
},
$set: {
department_id: 5
}
},
{
multi: true
}
);
更简洁的 updateMany
写法:
db.employee.updateMany(
{
"job": "Sales Representative"
},
{
$inc: {
salary: 10000
},
$set: {
department_id: 5
}
}
);
更新多个字段时的常见问题
踩坑警告:在单个查询中重复使用同一操作符时,MongoDB只会执行最后一次操作:
db.employee.updateMany(
{
"employee_id": 794875
},
{
$set: {
department_id: 3
},
$set: {
job:"Sales Manager"
}
}
);
结果只有 job
字段被更新,department_id
保持不变。正确做法是将多个字段放在同一个操作符中。
使用Java驱动更新字段
先建立数据库连接:
MongoClient mongoClient = new MongoClient(new MongoClientURI("mongodb://localhost:27017"));
MongoDatabase database = mongoClient.getDatabase("baeldung");
MongoCollection<Document> collection = database.getCollection("employee");
使用DBObject
BasicDBObject
继承自 LinkedHashMap
,采用键值对结构:
BasicDBObject searchQuery = new BasicDBObject("employee_id", 794875);
BasicDBObject updateFields = new BasicDBObject();
updateFields.append("department_id", 3);
updateFields.append("job", "Sales Manager");
BasicDBObject setQuery = new BasicDBObject();
setQuery.append("$set", updateFields);
UpdateResult updateResult = collection.updateMany(searchQuery, setQuery);
使用BSON文档
更现代的写法,利用 Filters
和 Updates
工具类:
UpdateResult updateQueryResult = collection.updateMany(
Filters.eq("employee_id", 794875),
Updates.combine(
Updates.set("department_id", 3),
Updates.set("job", "Sales Manager")
)
);
使用替换查询
简单粗暴的方案:直接用新文档替换旧文档:
db.employee.replaceOne(
{
"employee_id": 794875
},
{
"employee_id": 794875,
"employee_name": "David Smith",
"job": "Sales Manager",
"department_id": 3,
"salary": 30000,
"hire_date": NumberLong("1643969311817")
}
);
注意:替换操作会完全覆盖文档,未指定的字段将被删除。
结论
本文系统介绍了MongoDB多字段更新的三种核心方案:
- 操作符更新:通过
$set
/$inc
精准修改字段 - Java驱动实现:推荐使用BSON文档的链式调用
- 文档替换:适用于全量更新的场景
关键要点:
- 避免在单个查询中重复使用同一操作符
- 批量更新优先选择
updateMany
- 部分更新用操作符,全量更新用替换
完整代码示例可在GitHub仓库获取。