写入操作
本页内容
您可以对集合执行写入操作,以插入新文档、更新现有文档、替换现有文档或从集合中删除现有文档。
先决条件
您必须设置以下组件才能运行本指南中的代码示例
A
test.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 部署
首先,连接到 MongoDB 部署,然后声明和定义 MongoDatabase
和 MongoCollection
实例。
以下代码连接到在 localhost
的 27017
端口上运行的独立 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)
MongoDatabase
和 MongoCollection
实例是不可变的。在现有的 MongoDatabase
或 MongoCollection
实例上调用 withWriteConcern()
方法将返回一个新实例,而不会影响调用该方法时的实例。
在以下示例中,collWithWriteConcern
实例的写关注是 majority
,而集合的读取优先级不受影响
val collWithWriteConcern = collection.withWriteConcern(WriteConcern.MAJORITY)
您可以将 MongoClientSettings
、MongoDatabase
或 MongoCollection
实例构建为包含读取关注、读取优先级和写关注组合。
例如,以下代码在集合级别设置了所有三个
val collection = database.getCollection("restaurants") .withReadPreference(ReadPreference.primary()) .withReadConcern(ReadConcern.MAJORITY) .withWriteConcern(WriteConcern.MAJORITY)