环境配置
确保你的项目中已经添加了 MongoDB Java Driver 的依赖。

Maven (pom.xml)
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongodb-driver-sync</artifactId>
<version>4.11.1</version> <!-- 请使用最新版本 -->
</dependency>
Gradle (build.gradle)
implementation 'org.mongodb:mongodb-driver-sync:4.11.1' // 请使用最新版本
基础设置:连接 MongoDB
在执行任何更新操作之前,你需要先建立与 MongoDB 服务器的连接。
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import org.bson.Document;
public class MongoUpdateExample {
public static void main(String[] args) {
// 替换为你的 MongoDB 连接字符串
String uri = "mongodb://localhost:27017";
try (MongoClient mongoClient = MongoClients.create(uri)) {
// 连接到指定的数据库
MongoDatabase database = mongoClient.getDatabase("testDB");
// 获取指定的集合
MongoCollection<Document> collection = database.getCollection("users");
System.out.println("成功连接到 MongoDB 和集合 users");
// ... 在这里放置你的更新代码 ...
} catch (Exception e) {
e.printStackTrace();
}
}
}
更新单个文档 (updateOne)
updateOne 方法用于更新与查询条件匹配的第一个文档。

语法
collection.updateOne(filter, update)
filter(Filters): 用于定位要更新的文档的查询条件。update(Updates): 描述要执行哪些更新操作的文档。
示例:更新字段
假设我们有以下文档:
// { "_id": 1, "name": "Alice", "age": 30, "city": "New York" }
我们要将 Alice 的年龄更新为 31 岁。
// 1. 定义更新条件 (filter)
// 找到 name 为 "Alice" 的文档
Document filter = new Document("name", "Alice");
// 2. 定义更新操作 (update)
// 使用 $set 操作符来设置 "age" 字段为 31
Document update = new Document("$set", new Document("age", 31));
// 3. 执行更新
collection.updateOne(filter, update);
System.out.println("已更新 Alice 的年龄。");
示例:添加新字段
如果字段不存在,$set 会添加它。

// 更新条件
Document filter = new Document("name", "Alice");
// 更新操作:添加一个 "status" 字段
Document update = new Document("$set", new Document("status", "active"));
collection.updateOne(filter, update);
System.out.println("已为 Alice 添加 status 字段。");
示例:删除字段
使用 $unset 操作符可以删除一个字段。
// 更新条件
Document filter = new Document("name", "Alice");
// 更新操作:删除 "city" 字段
Document update = new Document("$unset", new Document("city", "")); // 值可以是任意值,通常为空字符串
collection.updateOne(filter, update);
System.out.println("已删除 Alice 的 city 字段。");
更新多个文档 (updateMany)
updateMany 方法用于更新与查询条件匹配的所有文档。
示例:批量更新
假设集合中有多个用户,我们想将所有城市为 "New York" 的用户的 status 字段更新为 "VIP"。
// 1. 定义更新条件
// 找到所有 city 为 "New York" 的文档
Document filter = new Document("city", "New York");
// 2. 定义更新操作
Document update = new Document("$set", new Document("status", "VIP"));
// 3. 执行批量更新
UpdateResult result = collection.updateMany(filter, update);
// 4. 查看更新结果
System.out.println("匹配的文档数: " + result.getMatchedCount());
System.out.println("被修改的文档数: " + result.getModifiedCount());
System.out.println("已批量更新所有 New York 用户的 status。");
注意: UpdateResult 对象非常有用,它告诉你操作影响了多少文档。
使用 Filters 和 Updates 助手类
虽然可以直接使用 Document,但 MongoDB 驱动提供了 Filters 和 Updates 助手类,它们能提供更好的类型安全和代码可读性。
示例:使用助手类重写 updateOne
import static com.mongodb.client.model.Filters.*;
import static com.mongodb.client.model.Updates.*;
// 1. 定义更新条件 (使用 Filters.eq)
// eq() 是 "equal" 的缩写
Bson filter = eq("name", "Alice");
// 2. 定义更新操作 (使用 Updates.set)
// set() 是 "$set" 的缩写
Bson update = set("age", 32);
// 3. 执行更新
collection.updateOne(filter, update);
System.out.println("使用助手类更新了 Alice 的年龄为 32。");
更新操作符示例 (Updates)
Updates 类提供了所有标准更新操作符的便捷方法:
set(field, value):$setunset(field):$unsetinc(field, value):$inc(增加数值)mul(field, value):$mul(乘以数值)rename(field, newName):$rename(重命名字段)setOnInsert(field, value):$setOnInsert(仅在 upsert 时设置)push(field, value):$push(向数组添加元素)pull(field, value):$pull(从数组移除元素)
示例:使用 $inc
// 将 Alice 的年龄增加 1
Bson filter = eq("name", "Alice");
Bson update = inc("age", 1); // age = age + 1
collection.updateOne(filter, update);
高级更新:数组操作
$push - 向数组添加元素
tags 字段不存在,$push 会创建它,如果它存在但不是数组,操作会失败。
// 假设文档为: { "_id": 2, "name": "Bob", "tags": ["mongodb"] }
Bson filter = eq("name", "Bob");
Bson update = push("tags", "java"); // 添加 "java" 到 tags 数组
collection.updateOne(filter, update);
// 更新后: { "_id": 2, "name": "Bob", "tags": ["mongodb", "java"] }
$pull - 从数组移除元素
移除所有匹配 value 的元素。
// 假设文档为: { "_id": 2, "name": "Bob", "tags": ["mongodb", "java", "mongodb"] }
Bson filter = eq("name", "Bob");
Bson update = pull("tags", "mongodb"); // 移除所有 "mongodb"
collection.updateOne(filter, update);
// 更新后: { "_id": 2, "name": "Bob", "tags": ["java"] }
Upsert 操作
"Upsert" 是 "update" 和 "insert" 的组合词,如果查询条件匹配到文档,则更新它;如果没有匹配到,则插入一个新文档。
如何实现
只需在 updateOne 或 updateMany 的选项中设置 upsert(true)。
import com.mongodb.client.model.UpdateOptions;
// 1. 定义更新条件
// 这个用户目前不存在
Bson filter = eq("username", "charlie");
// 2. 定义更新操作
// 如果插入,这个文档将被插入
Bson update = combine(
set("name", "Charlie"),
set("age", 25),
set("city", "London")
);
// 3. 定义选项,开启 upsert
UpdateOptions options = new UpdateOptions().upsert(true);
// 4. 执行 upsert 操作
UpdateResult result = collection.updateOne(filter, update, options);
// 5. 检查结果
if (result.getUpsertedId() != null) {
System.out.println("插入了新文档,ID 为: " + result.getUpsertedId().asObjectId().getValue());
} else {
System.out.println("更新了现有文档。");
}
注意: 当 upsert 插入新文档时,_id 字段由 MongoDB 自动生成,getUpsertedId() 会返回这个新 _id。
更新嵌套文档和数组
更新嵌套文档
使用 field.subField 的点表示法。
// 假设文档: { "_id": 3, "name": "David", "address": { "street": "123 Main St", "city": "Paris" } }
Bson filter = eq("name", "David");
Bson update = set("address.city", "Lyon"); // 更新嵌套的 city 字段
collection.updateOne(filter, update);
// 更新后: { "_id": 3, "name": "David", "address": { "street": "123 Main St", "city": "Lyon" } }
更新数组中的特定元素
使用 array[index] 的点表示法。
// 假设文档: { "_id": 4, "name": "Eve", "scores": [85, 90, 78] }
Bson filter = eq("name", "Eve");
Bson update = set("scores.1", 95); // 将索引为 1 的元素 (90) 更新为 95
collection.updateOne(filter, update);
// 更新后: { "_id": 4, "name": "Eve", "scores": [85, 95, 78] }
| 方法 | 描述 | 示例 |
|---|---|---|
updateOne(filter, update) |
更新匹配条件的第一个文档。 | updateOne(eq("name", "Alice"), set("age", 30)); |
updateMany(filter, update) |
更新匹配条件的所有文档。 | updateMany(eq("city", "NYC"), set("status", "VIP")); |
UpdateOptions().upsert(true) |
如果没有匹配的文档,则插入一个新文档。 | updateOne(filter, update, new UpdateOptions().upsert(true)); |
Filters 类 |
用于构建查询条件的助手类。 | Filters.eq(), Filters.gt(), Filters.in() |
Updates 类 |
用于构建更新操作的助手类。 | Updates.set(), Updates.inc(), Updates.push() |
UpdateResult |
updateOne 和 updateMany 的返回值,包含匹配和修改的计数。 |
result.getMatchedCount(); |
选择哪种方法取决于你的具体需求,对于简单的更新,直接使用 Document 即可;对于复杂的查询和更新,强烈推荐使用 Filters 和 Updates 助手类,它们能让你的代码更清晰、更不容易出错。
