文档菜单
文档首页
/ / /
Scala
/

写入操作

本页内容

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

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

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

  • Atest.restaurants 集合包含从文档 restaurants.json 中提取的文档,该文档位于文档资产 GitHub.

  • 以下导入语句

import org.mongodb.scala._
import org.mongodb.scala.model._
import org.mongodb.scala.model.Filters._
import org.mongodb.scala.model.Updates._
import org.mongodb.scala.model.UpdateOptions
import org.mongodb.scala.bson.BsonObjectId

注意

本指南使用 Observable 隐式作为

快速入门简介.

首先,连接到 MongoDB 部署,然后声明和定义 MongoDatabaseMongoCollection 实例。

以下代码连接到在 localhost27017 端口上运行的独立 MongoDB 部署。然后,定义 database 变量以引用 test 数据库,以及 collection 变量以引用 restaurants 集合

val mongoClient: MongoClient = MongoClient()
val database: MongoDatabase = mongoClient.getDatabase("test")
val collection: MongoCollection[Document] = database.getCollection("restaurants")

要了解有关连接到 MongoDB 部署的更多信息,请参阅 连接到 MongoDB 教程。

要将单个文档插入集合中,可以使用集合的insertOne()方法

val document = Document("name" -> "Café Con Leche" ,
"contact" -> Document("phone" -> "228-555-0149",
"email" -> "cafeconleche@example.com",
"location" -> Seq(-73.92502, 40.8279556)),
"stars" -> 3, "categories" -> Seq("Bakery", "Coffee", "Pastries"))
collection.insertOne(document).printResults()

注意

如果文档中没有指定顶级_id字段,MongoDB会自动生成一个值,并将其添加到插入的文档中。

要插入多个文档,可以使用集合的insertMany()方法,该方法接收一个要插入的文档列表作为参数。

以下示例将两个文档插入集合

val doc1 = Document("name" -> "Amarcord Pizzeria" ,
"contact" -> Document("phone" -> "264-555-0193",
"email" -> "amarcord.pizzeria@example.net",
"location" -> Seq(-73.88502, 40.749556)),
"stars" -> 2, "categories" -> Seq("Pizzeria", "Italian", "Pasta"))
val doc2 = Document("name" -> "Blue Coffee Bar" ,
"contact" -> Document("phone" -> "604-555-0102",
"email" -> "bluecoffeebar@example.com",
"location" -> Seq(-73.97902, 40.8479556)),
"stars" -> 5, "categories" -> Seq("Coffee", "Pastries"))
collection.insertMany(Seq(doc1, doc2)).printResults()

注意

如果文档中没有指定顶级_id字段,MongoDB会自动生成一个值,并将其添加到插入的文档中。

要更新集合中的现有文档,可以使用集合的updateOne()updateMany()方法。

您可以将过滤器文档传递给方法来指定要更新的文档。过滤器文档的指定与读取操作相同。为了方便创建过滤器对象,驱动程序提供了Filters辅助类。

要指定一个空过滤器并匹配集合中的所有文档,请使用空Document对象作为过滤器。

要更改文档中的一个字段,MongoDB提供了更新运算符。要使用更新运算符指定要执行的操作,创建一个更新文档。有关更新运算符的更多信息,请参阅服务器手册中的更新运算符

为了方便创建更新文档,驱动程序提供了Updates辅助类。有关使用构建器指定更新的更多信息,请参阅更新指南。

重要

字段_id是不可变的,因此您不能更改文档中_id字段的值。

updateOne()方法更新单个文档,即使过滤器条件匹配集合中的多个文档。

以下操作更新了restaurants集合中的一个文档,该文档中_id字段的值为BsonObjectId("57506d62f57802807471dd41")

collection.updateOne(
equal("_id", BsonObjectId("57506d62f57802807471dd41")),
combine(set("stars", 1), set("contact.phone", "228-555-9999"), currentDate("lastModified")))
.printResults()

具体来说,该操作使用以下方法:

  • Updates.set()stars字段的值设置为1,将contact.phone字段的值设置为"228-555-9999"

  • Updates.currentDate() 用于将lastModified字段修改为当前日期。如果lastModified字段不存在,操作员将该字段添加到文档中。

updateMany() 方法更新所有匹配筛选条件的文档。

以下对restaurants集合的操作更新了所有stars字段的值为2的文档。

collection.updateMany(
equal("stars", 2),
combine(set("stars", 0), currentDate("lastModified")))
.println()

具体来说,该操作使用以下方法:

  • Updates.set()stars字段的值设置为0

  • Updates.currentDate()lastModified字段设置为当前日期。如果lastModified字段不存在,操作员将该字段添加到文档中。

当使用updateOne()updateMany()方法时,您可以包含一个UpdateOptions文档来指定upsert选项或bypassDocumentationValidation选项。

collection.updateOne(
equal("_id", 1),
combine(set("name", "Fresh Breads and Tulips"), currentDate("lastModified")),
UpdateOptions().upsert(true).bypassDocumentValidation(true))
.printResults()

要替换集合中的现有文档,您可以使用集合的 replaceOne() 方法。

重要

_id 字段是不可变的,因此您不能替换文档中的 _id 字段。

您可以将过滤器文档传递给 replaceOne() 方法以指定要替换的文档。过滤器文档规范与读取操作相同。为了方便创建过滤器对象,驱动程序提供了 Filters 辅助类。

要指定一个空过滤器并匹配集合中的所有文档,请使用空Document对象作为过滤器。

replaceOne() 方法最多替换一个文档,即使过滤器条件匹配集合中的多个文档。

要替换文档,请将新的文档传递给 replaceOne() 方法。

重要

替换文档可以包含与原始文档不同的字段。在替换文档中,您可以省略 _id 字段,因为 _id 字段是不可变的。但是,如果您包含 _id 字段,则不能指定不同的 _id 字段值。

以下操作是在 restaurants 集合中,替换 _id 字段值为 BsonObjectId("57506d62f57802807471dd41") 的文档。

collection.replaceOne(
equal("_id", BsonObjectId("57506d62f57802807471dd41")),
Document("name" -> "Green Salads Buffet", "contact" -> "TBD",
"categories" -> Seq("Salads", "Health Foods", "Buffet")))
.printResults()

当使用 replaceOne() 方法时,您可以包含一个 UpdateOptions 文档来指定 upsert 选项或 bypassDocumentationValidation 选项。

collection.replaceOne(
equal("name", "Orange Patisserie and Gelateria"),
Document("stars" -> 5, "contact" -> "TBD",
"categories" -> Seq("Cafe", "Pastries", "Ice Cream")),
UpdateOptions().upsert(true).bypassDocumentValidation(true))
.printResults()

要删除集合中的文档,可以使用 deleteOne()deleteMany() 方法。

您可以将过滤文档传递给方法来指定要删除的文档。过滤文档的规范与读取操作相同。为了方便创建过滤对象,驱动程序提供了Filters辅助类。

要指定一个空过滤器并匹配集合中的所有文档,请使用空Document对象作为过滤器。

deleteOne()方法最多删除一个文档,即使过滤条件与集合中的多个文档匹配。

以下对restaurants集合的操作删除了_id字段的值为ObjectId("57506d62f57802807471dd41")的文档。

collection.deleteOne(equal("_id", new ObjectId("57506d62f57802807471dd41"))).subscribe(new ObservableSubscriber<DeleteResult>())

deleteMany()方法删除所有匹配过滤条件的文档。

以下对restaurants集合的操作删除了stars字段的值为4的所有文档。

collection.deleteMany(equal("stars", 4)).printResults()

写入关注描述了从MongoDB请求的写入操作的确认级别。

您可以在以下级别配置写入关注

  • 在以下方式中的MongoClient

    • 通过创建一个MongoClientSettings实例

      val mongoClient: MongoClient = MongoClient(MongoClientSettings.builder()
      .applyConnectionString(ConnectionString("mongodb://host1,host2"))
      .writeConcern(WriteConcern.MAJORITY)
      .build())
    • 通过创建一个ConnectionString实例

      val mongoClientt = MongoClient("mongodb://host1:27017,host2:27017/?w=majority")
  • MongoDatabase 中,使用 withWriteConcern() 方法

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

    val collection = database.getCollection("restaurants").withWriteConcern(WriteConcern.MAJORITY)

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

在以下示例中,collWithWriteConcern 实例的写关注是 majority,而集合的读取优先级不受影响

val collWithWriteConcern = collection.withWriteConcern(WriteConcern.MAJORITY)

您可以将 MongoClientSettingsMongoDatabaseMongoCollection 实例构建为包含读取关注、读取优先级和写关注组合。

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

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

返回

使用中加密