Docs 菜单
Docs 主页
/ / /
Java Reactive Streams 驱动程序
/

写入操作

在此页面上

  • 先决条件
  • 连接到 MongoDB 部署
  • 插入文档
  • 插入多个文档
  • 更新现有文档
  • 筛选器
  • 更新操作符
  • 更新单份文档
  • 更新多个文档
  • UpdateOptions
  • 替换现有文档
  • 筛选器
  • 替换文档
  • UpdateOptions
  • Delete Documents
  • 筛选器
  • 删除单个文档
  • 删除多个文档
  • 写关注

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

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

  • 一个test.restaurants restaurants.json集合,其中填充了来自 文档资产Github 中的 文件的文档。

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

以下代码连接到在端口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字段的值设置为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");
  • MongoDatabase中,使用withWriteConcern()方法:

    MongoDatabase database = mongoClient.getDatabase("test").withWriteConcern(WriteConcern.MAJORITY);
  • MongoCollection中,使用withWriteConcern()方法:

    MongoCollection<Document> collection = database
    .getCollection("restaurants")
    .withWriteConcern(WriteConcern.MAJORITY);

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

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

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

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

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

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

后退

客户端加密