数据库和集合
MongoDB 以分层结构组织数据。 MongoDB 部署包含一个或多个数据库,每个数据库又包含一个或多个集合。 在每个集合中,MongoDB 将数据存储为包含字段与值对的文档。
先决条件
您必须在程序中包含以下 import 语句才能运行本指南中的代码示例:
import org.mongodb.scala._ import org.mongodb.scala.model.Filters._
注意
本指南使用 Observable
隐式,如快速入门入门知识中所述。
连接到 MongoDB 部署
首先,连接到正在运行的 MongoDB 部署。
以下代码连接到在端口27017
上的localhost
上运行的独立 MongoDB 部署:
val mongoClient = MongoClient()
要了解有关连接到 MongoDB 部署的更多信息,请参阅连接到 MongoDB教程。
访问数据库
将MongoClient
实例连接到 MongoDB 部署后,使用`getDatabase()
方法访问数据库。
将数据库名称作为参数传递给getDatabase()
方法。 如果数据库不存在,MongoDB 会在您向数据库插入任何数据时创建该数据库。
以下示例将访问test
数据库:
val database: MongoDatabase = mongoClient.getDatabase("test")
注意
MongoDatabase
实例不可变。 要了解详情,请参阅本指南的不变性部分。
访问集合
创建MongoDatabase
实例后,使用getCollection()
方法从该数据库访问集合。
将集合名称作为参数传递给getCollection()
方法。
使用在上一节中创建的database
实例,以下代码访问名为myTestCollection
的集合:
val coll: MongoCollection[Document] = database.getCollection("myTestCollection")
注意
MongoCollection
实例不可变。 要了解更多信息,请参阅本指南的“不变性”部分。
如果具有该名称的集合不存在,MongoDB 会在您首次将数据插入该集合时创建该集合。
您还可以使用各种选项直接创建集合,例如设置最大大小或创建文档验证规则。
创建集合
驱动程序提供了createCollection()
方法来直接创建集合。 创建集合时,可以使用CreateCollectionOptions
类指定各种集合选项,例如最大大小或文档验证规则。
如果未指定任何选项,则无需直接创建集合,因为 MongoDB 会在您首次插入数据时自动创建新集合。
固定大小集合
以下操作将创建一个限制为1 MB 的固定大小集合:
database.createCollection("cappedCollection", CreateCollectionOptions().capped(true).sizeInBytes(0x100000)) .printResults()
文档验证
MongoDB 允许您在更新和插入期间验证文档。 验证规则是使用ValidationOptions
类在集合级别指定的,该类采用指定验证规则或表达式的筛选器文档。
以下示例将创建一个具有模式验证功能的集合:
ValidationOptions collOptions = ValidationOptions().validator( Filters.or(Filters.exists("email"), Filters.exists("phone"))) database.createCollection("contacts", CreateCollectionOptions().validationOptions(collOptions)) .printResults()
获取集合列表
您可以使用MongoDatabase.listCollectionNames()
方法获取数据库中集合的列表:
database.listCollectionNames().printResults()
删除集合
您可以使用MongoCollection.drop()
方法删除一个集合并删除该集合中的所有数据:
val collection: MongoCollection[Document] = database.getCollection("contacts") collection.drop().printResults()
不变性
MongoDatabase
和MongoCollection
实例是不可变的。 要从具有不同属性(例如不同的读关注、读取偏好和写关注)的现有实例创建新实例, MongoDatabase
和MongoCollection
类提供了以下方法:
MongoDatabase.withReadConcern()
MongoDatabase.withReadPreference()
MongoDatabase.withWriteConcern()
MongoCollection.withReadConcern()
MongoCollection.withReadPreference()
MongoCollection.withWriteConcern()
CodecRegistry
getCollection()
方法的重载允许您指定不同的类来表示 BSON 文档。 例如,在执行 CRUD 操作时,您可能希望使用严格且类型安全的BsonDocument
类来对文档进行建模:
import org.mongodb.scala.bson._ val collection: MongoCollection[BsonDocument] = database.getCollection[BsonDocument]("mycoll") // insert a document val document = BsonDocument("{x: 1}") collection.insertOne(document).printResults() document.append("x", BsonInt32(2)).append("y", BsonInt32(3)) // replace a document collection.replaceOne(Filters.equal("_id", document.get("_id")), document) .printResults() // find documents collection.find().printResults()
任何类都必须满足两个要求才能以此方式使用:
Codec
该类的实例必须在MongoCollection
的CodecRegistry
中注册。Codec
实例必须是对完整 BSON 文档进行编码和解码的实例,而不仅仅是像Int32
这样的单个 BSON 值。
默认情况下, MongoCollection
配置有四个类的Codec
实例:
Document
(ScalaBsonDocument
包装器)BsonDocument
Document
(Java 驱动程序的松散类型Document
类)BasicDBObject
应用程序可通过自定义CodecRegistry
来自由注册其他类的Codec
实现。 新的CodecRegistry
实例可在以下级别进行配置:
在
MongoClientSettings
内的MongoClient
中在
MongoDatabase
的withCodecRegistry
方法中在
MongoCollection
的withCodecRegistry
方法中
考虑对UUID
类的实例进行编码和解码的情况。 默认情况下,驱动程序使用与其他 MongoDB 驱动程序不兼容的字节顺序对UUID
的实例进行编码,更改默认值会很危险。
需要跨多个驱动程序互操作性的新应用程序可以更改该默认值,并且可以通过指定 CodecRegistry
// replaces the default UuidCodec with one that uses the new standard UUID representation import org.bson.UuidRepresentation import org.bson.codecs.UuidCodec import org.bson.codecs.configuration.CodecRegistries val codecRegistry = CodecRegistries.fromRegistries( CodecRegistries.fromCodecs(new UuidCodec(UuidRepresentation.STANDARD)), MongoClient.DEFAULT_CODEC_REGISTRY) // globally val settings = MongoClientSettings.builder() .codecRegistry(codecRegistry).build() val client = MongoClient(settings) // or at the database level val database = client.getDatabase("mydb") .withCodecRegistry(codecRegistry) // or at the collection level val collection = database.getCollection("mycoll") .withCodecRegistry(codecRegistry)