写入操作
您可以对集合执行写入操作以插入新文档、更新现有文档、替换现有文档或删除现有文档。
先决条件
您必须设置以下组件才能运行本指南中的代码示例
A
test.restaurants集合,该集合包含从文档restaurants.json中获取的文档,该文档位于文档资源 GitHub.以下导入语句
import com.mongodb.*; import com.mongodb.client.MongoClients; import com.mongodb.client.MongoClient; import com.mongodb.client.MongoCollection; import com.mongodb.client.MongoDatabase; import com.mongodb.client.model.Filters; import static com.mongodb.client.model.Filters.*; import static com.mongodb.client.model.Updates.*; import com.mongodb.client.model.UpdateOptions; import com.mongodb.client.result.*; import org.bson.Document; import org.bson.types.ObjectId; import java.util.List; import java.util.Arrays; import java.util.ArrayList;
重要
本指南使用 Subscriber 实现,这些实现已在快速入门指南中描述中.
连接到 MongoDB 部署
首先,连接到 MongoDB 部署,然后声明并定义 MongoDatabase 和 MongoCollection 实例。
以下代码连接到在 localhost 上运行并监听 27017 端口的独立 MongoDB 部署。然后,它定义 database 变量以引用 test 数据库,以及 collection 变量以引用 restaurants 集合
MongoClient mongoClient = MongoClients.create(); MongoDatabase database = mongoClient.getDatabase("test"); MongoCollection<Document> collection = database.getCollection("restaurants");
有关连接到 MongoDB 部署的更多信息,请参阅连接到 MongoDB 指南。
插入文档
要将单个文档插入到集合中,您可以使用集合的 insertOne() 方法
Document document = new Document("name", "Café Con Leche") .append("contact", new Document("phone", "228-555-0149") .append("email", "cafeconleche@example.com") .append("location",Arrays.asList(-73.92502, 40.8279556))) .append("stars", 3) .append("categories", Arrays.asList("Bakery", "Coffee", "Pastries")); collection.insertOne(document).subscribe(new ObservableSubscriber<Void>());
注意
如果文档中没有指定顶级 id 字段,MongoDB 会自动生成一个值,并将此字段添加到插入的文档中。
插入多个文档
要插入多个文档,可以使用集合的 insertMany() 方法,该方法接受一个要插入的文档列表作为参数。
以下示例将两个文档插入集合中
Document doc1 = new Document("name", "Amarcord Pizzeria") .append("contact", new Document("phone", "264-555-0193") .append("email", "amarcord.pizzeria@example.net") .append("location",Arrays.asList(-73.88502, 40.749556))) .append("stars", 2) .append("categories", Arrays.asList("Pizzeria", "Italian", "Pasta")); Document doc2 = new Document("name", "Blue Coffee Bar") .append("contact", new Document("phone", "604-555-0102") .append("email", "bluecoffeebar@example.com") .append("location",Arrays.asList(-73.97902, 40.8479556))) .append("stars", 5) .append("categories", Arrays.asList("Coffee", "Pastries")); List<Document> documents = new ArrayList<Document>(); documents.add(doc1); documents.add(doc2); collection.insertMany(documents).subscribe(new ObservableSubscriber<Void>());;
注意
如果文档中没有指定顶级 id 字段,MongoDB 会自动生成一个值,并将此字段添加到插入的文档中。
更新现有文档
要更新集合中的现有文档,可以使用集合的 updateOne() 或 updateMany() 方法。
过滤器
可以将过滤器文档传递给方法以指定要更新的文档。过滤器文档的指定与读取操作相同。为了方便创建过滤器对象,驱动程序提供了 Filters 辅助类。
要指定空过滤器并匹配集合中的所有文档,请使用空 Document 对象作为过滤器。
更新运算符
要更改文档中的字段,MongoDB 提供了更新运算符。要使用更新运算符指定要执行的修改,请创建一个更新文档。有关更新运算符的更多信息,请参阅服务器手册中的更新运算符。
为了方便创建更新文档,驱动程序提供了 Updates 辅助类。
重要
id 字段是不可变的,因此您不能更改文档中 id 字段的值。
更新单个文档
updateOne() 方法更新单个文档,即使筛选条件与集合中的多个文档匹配。
以下对 restaurants 集合的操作更新了 id 字段值为 ObjectId("57506d62f57802807471dd41") 的文档。
collection.updateOne( eq("_id", new ObjectId("57506d62f57802807471dd41")), combine(set("stars", 1), set("contact.phone", "228-555-9999"), currentDate("lastModified")) ).subscribe(new ObservableSubscriber<UpdateResult>());
具体来说,操作使用了以下方法
Updates.set()将stars字段的值设置为1和contact.phone字段的值为"228-555-9999"Updates.currentDate()将lastModified字段修改为当前日期。如果lastModified字段不存在,则运算符会将该字段添加到文档中。
更新多个文档
updateMany() 方法更新所有匹配过滤器条件的文档。
以下对 restaurants 集合的操作更新了所有 stars 字段值为 2 的文档
collection.updateMany( eq("stars", 2), combine(set("stars", 0), currentDate("lastModified")) ).subscribe(new ObservableSubscriber<UpdateResult>());
具体来说,操作使用了以下方法
Updates.set()将stars字段的值设置为0Updates.currentDate()将lastModified字段设置为当前日期。如果lastModified字段不存在,操作符将字段添加到文档中。
更新选项
当使用 updateOne() 和 updateMany() 方法时,您可以在 UpdateOptions 文档中包含 upsert 选项或 bypassDocumentationValidation 选项
collection.updateOne( eq("_id", 1), combine(set("name", "Fresh Breads and Tulips"), currentDate("lastModified")), new UpdateOptions().upsert(true).bypassDocumentValidation(true) ).subscribe(new ObservableSubscriber<UpdateResult>());
替换现有文档
要替换集合中的现有文档,您可以使用集合的 replaceOne() 方法。
重要
id字段是不可变的,因此您不能在文档中替换id字段。
过滤器
您可以将过滤器文档传递给replaceOne()方法来指定要替换哪个文档。过滤器文档的指定与读取操作相同。为了方便创建过滤器对象,驱动程序提供了Filters辅助类。
要指定空过滤器并匹配集合中的所有文档,请使用空 Document 对象作为过滤器。
replaceOne()方法最多替换一个文档,即使过滤器条件与集合中的多个文档匹配。
替换文档
要替换文档,请将新文档传递给replaceOne()方法。
重要
替换文档可以包含与原始文档不同的字段。在替换文档中,由于id字段是不可变的,因此您可以省略id字段。但是,如果您包含id字段,则不能为id字段指定不同的值。
以下对restaurants集合的操作替换了id字段值为ObjectId("57506d62f57802807471dd41")的文档
collection.replaceOne( eq("_id", new ObjectId("57506d62f57802807471dd41")), new Document("name", "Green Salads Buffet") .append("contact", "TBD") .append("categories", Arrays.asList("Salads", "Health Foods", "Buffet")) ).subscribe(new ObservableSubscriber<UpdateResult>());
更新选项
当使用replaceOne()方法时,您可以包含一个UpdateOptions文档来指定upsert选项或bypassDocumentationValidation选项。
collection.replaceOne( eq("name", "Orange Patisserie and Gelateria"), new Document("stars", 5) .append("contact", "TBD") .append("categories", Arrays.asList("Cafe", "Pastries", "Ice Cream")), new UpdateOptions().upsert(true).bypassDocumentValidation(true) ).subscribe(new ObservableSubscriber<UpdateResult>());
删除文档
要删除集合中的文档,可以使用 deleteOne() 和 deleteMany() 方法。
过滤器
您可以将过滤器文档传递给这些方法以指定要删除的文档。过滤器文档的指定方式与读取操作相同。为了便于创建过滤器对象,驱动程序提供了 Filters 辅助类。
要指定空过滤器并匹配集合中的所有文档,请使用空 Document 对象作为过滤器。
删除单个文档
deleteOne() 方法最多删除单个文档,即使过滤器条件与集合中的多个文档匹配。
以下对 restaurants 集合的操作将删除具有 _id 字段值为 ObjectId("57506d62f57802807471dd41") 的文档。
collection .deleteOne(eq("_id", new ObjectId("57506d62f57802807471dd41"))) .subscribe(new ObservableSubscriber<DeleteResult>());
删除多个文档
deleteMany() 方法删除所有匹配过滤条件的文档。
以下对 restaurants 集合的操作删除了所有 stars 字段值为 4 的文档。
collection .deleteMany(eq("stars", 4)) .subscribe(new ObservableSubscriber<DeleteResult>());
写关注
写关注描述了 MongoDB 对写操作请求的确认级别。
您可以在以下级别配置写关注
在以下方式中配置
MongoClient通过创建
MongoClientSettings实例MongoClient mongoClient = MongoClients.create(MongoClientSettings.builder() .applyConnectionString(new ConnectionString("mongodb://host1,host2")) .writeConcern(WriteConcern.MAJORITY) .build()); 通过创建
ConnectionString实例MongoClient mongoClient = MongoClients.create("mongodb://host1:27017,host2:27017/?w=majority");
通过使用
withWriteConcern()方法在MongoDatabase中MongoDatabase database = mongoClient.getDatabase("test").withWriteConcern(WriteConcern.MAJORITY); 通过使用
withWriteConcern()方法在MongoCollection中MongoCollection<Document> collection = database .getCollection("restaurants") .withWriteConcern(WriteConcern.MAJORITY);
MongoDatabase 和 MongoCollection 实例是不可变的。在现有的 MongoDatabase 或 MongoCollection 实例上调用 withWriteConcern() 会返回一个新的实例,并且不会影响调用方法时的实例。
在以下示例中,collWithWriteConcern 实例的写关注为 majority,而集合的读偏好不受影响
MongoCollection<Document> collWithWriteConcern = collection .withWriteConcern(WriteConcern.MAJORITY);
您可以将 MongoClientSettings、MongoDatabase 或 MongoCollection 实例构建为包括读取关注、读取偏好和写关注的组合。
例如,以下代码在集合级别设置了所有三个
Collection = database.getCollection("restaurants") .withReadPreference(ReadPreference.primary()) .withReadConcern(ReadConcern.MAJORITY) .withWriteConcern(WriteConcern.MAJORITY);