文档菜单
文档首页
/ / /
Java反应式流驱动程序
/

写入操作

本页内容

  • 先决条件
  • 连接到MongoDB部署
  • 插入文档
  • 插入多个文档
  • 更新现有文档
  • 过滤器
  • 更新运算符
  • 更新单个文档
  • 更新多个文档
  • 更新选项
  • 替换现有文档
  • 过滤器
  • 替换文档
  • 更新选项
  • 删除文档
  • 过滤器
  • 删除单个文档
  • 删除多个文档
  • 写关注

您可以对集合执行写入操作以插入新文档、更新现有文档、替换现有文档或删除现有文档。

您必须设置以下组件才能运行本指南中的代码示例

  • Atest.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 部署,然后声明并定义 MongoDatabaseMongoCollection 实例。

以下代码连接到在 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 字段的值设置为 1contact.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 字段的值设置为 0

  • Updates.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);

MongoDatabaseMongoCollection 实例是不可变的。在现有的 MongoDatabaseMongoCollection 实例上调用 withWriteConcern() 会返回一个新的实例,并且不会影响调用方法时的实例。

在以下示例中,collWithWriteConcern 实例的写关注为 majority,而集合的读偏好不受影响

MongoCollection<Document> collWithWriteConcern = collection
.withWriteConcern(WriteConcern.MAJORITY);

您可以将 MongoClientSettingsMongoDatabaseMongoCollection 实例构建为包括读取关注、读取偏好和写关注的组合。

例如,以下代码在集合级别设置了所有三个

Collection = database.getCollection("restaurants")
.withReadPreference(ReadPreference.primary())
.withReadConcern(ReadConcern.MAJORITY)
.withWriteConcern(WriteConcern.MAJORITY);

返回

客户端加密