Overview
Scala驱动程序包含两种特定于 Scala 的BSON文档表示形式。根据 Scala 集合库的惯例,Document 类型有不可变和可变实现。Document的根本的实现使用类型安全的 BsonDocument 类。BSON类可从 org.mongodb.scala.bson命名空间中获取,其中包括类型别名和伴生对象。这些对象应该足以满足许多使用案例,但对于高级使用案例,您可能需要直接使用 org.bson命名空间中的类。
重要
重复的键名
未定义服务器对文档中重复键名的行为。对具有重复键名称的文档进行解码时,驱动程序将分配与重复键关联的最后一个值。存储此类文档将导致其他值丢失。
注意
Scala Document类实现TraversableLike[(String,
BsonValue)] ,通用 API 镜像Map[String,
BsonValue]值。 但是,与Map不同, TraversableLike的实现支持严格的类型安全,因为值类型没有差异。
BsonValue 是org.bson库中 BSON 类型的类型安全表示形式,表示特定的值类型。 最常用的值类型如下:
BSON 类型 | Scala 类型 |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
可以更改或扩展这些映射,以下各节将介绍这一过程。
以下各部分介绍了两个主要的Document类。
不可变文档
与 Scala 集合库类似,不可变类是首选类。 为方便起见,它以org.mongodb.scala.Document和org.mongodb.scala.bson.Document为别名,并且可从org.mongodb.scala.bson.collection.immutable.Document中获取。
这种类型的实例保证对每个人来说都是不可变的。 这样的集合一旦创建就永远不会改变。 因此,可以确信的是,在不同时间点重复访问相同的集合值将始终生成包含相同元素的集合。
import org.mongodb.scala.bson._ val doc1 = Document("AL" -> BsonString("Alabama")) val doc2 = doc1 + ("AK" -> BsonString("Alaska")) val doc3 = doc2 ++ Document("AR" -> BsonString("Arkansas"), "AZ" -> BsonString("Arizona"))
可变文档
要获取可变的Document类型,您需要从org.mongodb.scala.collections.mutable.Document中显式导入。 可以就地更新或扩展可变的Document 。 这意味着您可以更改、添加或删除Document的元素,但附带效果是。 与 Scala 集合类似,在处理可变类型时,您需要了解哪些代码更改了哪些集合以及何时更改。
import org.mongodb.scala.bson._ import org.mongodb.scala.bson.collection.mutable.Document val doc = Document("AL" -> BsonString("Alabama")) val doc1 = doc + ("AK" -> BsonString("Alaska")) // doc not mutated but new doc created doc1 ++= Document("AR" -> BsonString("Arkansas"), "AZ" -> BsonString("Arizona")) // doc1 mutated as ++= changes in place.
隐式转换
对于许多BsonValue类型,明显存在来自 Scala 类型的直接映射。 例如, String映射到BsonString , Int映射到BsonInt32 , Long映射到BsonInt64 。 为方便起见,这些类型可直接与Document类型一起使用,并由BsonMagnets对象中的约定特征进行转换。 只要任何给定类型的范围内存在隐式BsonTransformer ,则该类型就可以转换为BsonValue 。
默认,以下BsonTransformers在范围内:
Scala 类型 | BsonValue |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import org.mongodb.scala.Document val doc1 = Document("AL" -> "Alabama") val doc2 = doc1 + ("AK" -> "Alaska") val doc3 = doc2 ++ Document("AR" -> "Arkansas", "population" -> 2.966)
这是通过使用 磁体模式 来实现的,您可以在 spray.io 上的磁体模式博文 中学习;了解更多信息。
在 API 中,我们通常期望单个值、键值对或多个键值对(例如BsonValue 、( String 、 BsonValue )或Iterable[(String, BsonValue)] ),我们要求任何可以成为这些类型(通过CanBeX特征)处理符合正确类型所需的隐式转换。 这些特征是CanBeBsonValue 、 CanBeBsonElement和CanBeBsonElements 。
一个这样的示例是将键值对添加到Document或值列表中:
val doc1 = Document("AL" -> "Alabama") val doc2 = Document("codes" -> List("AL", "AK", "AR"))
Bson
该驱动程序还包含一个名为Bson的小而强大的接口。 任何表示 BSON 文档的类(无论是包含在驱动程序本身中还是来自第三方)都可以实现此接口,然后可以在高级 API 中需要 BSON 文档的任何位置使用。 例如:
collection.find(Document("x" -> 1)) collection.find(Filters.eq("x", 1))