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