您可以执行写入操作以插入新文档、更新现有文档、替换现有文档或删除集合中的现有文档。
先决条件
您必须设置以下组件才能运行本指南中的代码示例:
一个
test.restaurants集合,其中填充了来自文档资产Github中restaurants.json文件的文档。以下 import 语句:
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实例。
以下代码连接到在端口27017上的localhost上运行的独立 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 提供了更新操作符。 要指定使用更新操作符执行的修改,请创建更新文档。 要了解有关更新操作符的更多信息,请参阅 MongoDB Server手册中的 更新操作符 。
为了便于创建更新文档,驱动程序提供了 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字段不存在,操作符会将该字段添加到文档中。
UpdateOptions
使用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>());
UpdateOptions
使用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>());
Delete Documents
要删除集合中的文档,可以使用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");
在
MongoDatabase中,使用withWriteConcern()方法:MongoDatabase database = mongoClient.getDatabase("test").withWriteConcern(WriteConcern.MAJORITY); 在
MongoCollection中,使用withWriteConcern()方法:MongoCollection<Document> collection = database .getCollection("restaurants") .withWriteConcern(WriteConcern.MAJORITY);
MongoDatabase 和MongoCollection实例是不可变的。 在现有MongoDatabase或MongoCollection实例上调用withWriteConcern()会返回一个新实例,并且不会影响调用该方法的实例。
在以下示例中, collWithWriteConcern实例的写关注为majority ,而collection的读取偏好不受影响:
MongoCollection<Document> collWithWriteConcern = collection .withWriteConcern(WriteConcern.MAJORITY);
您可以构建MongoClientSettings 、 MongoDatabase或MongoCollection实例以包含读关注、读取偏好和写关注的组合。
例如,以下代码在集合级别设置所有三个:
Collection = database.getCollection("restaurants") .withReadPreference(ReadPreference.primary()) .withReadConcern(ReadConcern.MAJORITY) .withWriteConcern(WriteConcern.MAJORITY);