Docs Menu
Docs Home
/ / /
Scala
/

Documents

On this page

  • Overview
  • Immutable Documents
  • Mutable Documents
  • Implicit Conversions
  • Bson

The Scala driver includes two Scala-specific representations for BSON documents. Following the convention from the Scala collections library, there are immutable and mutable implementations of the Document type. The underlying implementations of Document use the type-safe BsonDocument class. The BSON classes are available from the org.mongodb.scala.bson namespace, which includes type aliases and companion objects. These objects should suffice for many use cases, but for advanced use cases you may need to use classes from the org.bson namespace directly.

Important

Duplicate Key Names

The server’s behavior regarding duplicate key names in a document is undefined. When a document with duplicate key names is decoded, the driver will assign the last value associated with the duplicate key. Storing such a document will cause the other values to be lost.

Note

The Scala Document classes implement TraversableLike[(String, BsonValue)] and the general API mirrors that of a Map[String, BsonValue] value. However, unlike Map, implementations of TraversableLike enable strict type safety as there is no variance in the value type.

BsonValue is the type-safe representation of a BSON type from the org.bson library and represents specific value types. The most commonly used value types are as follows:

BSON Type
Scala Type

Document

org.mongodb.scala.bson.Document

Array

List

Date

Date or int (milliseconds since epoch)

Boolean

Boolean

Double

Double

Int32

Integer

Int64

Long

String

String

Binary

Array[Byte]

ObjectId

ObjectId

Null

None

It is possible to change or extend these mappings, a process described in the following sections.

The following sections describe the two main Document classes.

Similar to the Scala collections library, the immutable class is the preferred class. For convenience, it is aliased to org.mongodb.scala.Document and org.mongodb.scala.bson.Document as well as being available from org.mongodb.scala.bson.collection.immutable.Document.

Instances of this type are guaranteed to be immutable for everyone. Such a collection will never change after it is created. Therefore, you can rely on the fact that accessing the same collection value repeatedly at different points in time will always yield a collection with the same elements.

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"))

To get the mutable Document type, you need to import it explicitly from org.mongodb.scala.collections.mutable.Document. The mutable Document can be updated or extended in place. This means you can change, add, or remove elements of the Document as a side effect. Similar to Scala collections, when dealing with mutable types you need to understand which code changes which collection and when.

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.

For many of the BsonValue types, there are obvious direct mappings from a Scala type. For example, a String maps to BsonString, an Int maps to BsonInt32 and a Long maps to a BsonInt64. For convenience, these types can be used directly with Document types and they are converted by the contract traits in the BsonMagnets object. As long as there is an implicit BsonTransformer in scope for any given type, then that type can be converted into a BsonValue.

The following BsonTransformers are in scope by default:

Scala Type
BsonValue

Boolean

BsonBoolean

String

BsonString

Array[Byte]

BsonBinary

Regex

BsonRegex

Date

BsonDateTime

ObjectId

BsonObjectId

Int

BsonInt32

Long

BsonInt64

Double

BsonDouble

immutable.Document

BsonDocument

mutable.Document

BsonDocument

Option[T]

BsonValue where T has a BsonTransformer

Seq[(String, T)]

BsonDocument where T has a BsonTransformer

Seq[T]

BsonArray where T has a BsonTransformer

BsonValue

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)

This is achieved by making use of the Magnet Pattern, which you can learn more about in the Magnet Pattern blog post on spray.io.

In the API where we would normally expect a single value or a key-value pair or many key value pairs, such as BsonValue, (String, BsonValue) or Iterable[(String, BsonValue)], we require anything that can become those types via CanBeX traits that handle the implicit conversions necessary to conform to the correct types. These traits are CanBeBsonValue, CanBeBsonElement and CanBeBsonElements.

One such example is adding a key-value pair to a Document or a list of values:

val doc1 = Document("AL" -> "Alabama")
val doc2 = Document("codes" -> List("AL", "AK", "AR"))

The driver also contains a small but powerful interface called Bson. Any class that represents a BSON document, whether included in the driver itself or from a third party, can implement this interface and can then be used any place in the high-level API where a BSON document is required. For example:

collection.find(Document("x" -> 1))
collection.find(Filters.eq("x", 1))

Back

BSON Implementation