Skip to content

Commit c9d3744

Browse files
authored
DOCSP-38341: documents (#6)
* DOCSP-38341: documents * fix tree * CC PR fixes
1 parent 3682268 commit c9d3744

File tree

3 files changed

+250
-2
lines changed

3 files changed

+250
-2
lines changed

snooty.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ intersphinx = [ "https://www.mongodb.com/docs/manual/objects.inv",
77

88
sharedinclude_root = "https://raw.githubusercontent.com/10gen/docs-shared/main/"
99

10-
toc_landing_pages = []
10+
toc_landing_pages = [
11+
"/bson"
12+
]
1113

1214
[constants]
1315
driver-short = "Scala driver"

source/bson.txt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ BSON Implementation
1111
.. meta::
1212
:keywords: documents, storage, codec
1313

14+
.. toctree::
15+
16+
/bson/documents/
17+
1418
The BSON library comprehensively supports `BSON
1519
<https://bsonspec.org/>`__, the data storage and network transfer format
1620
that MongoDB uses for documents. BSON, short
@@ -28,7 +32,7 @@ implementation:
2832

2933
.. TODO add links
3034

31-
- Documents: describes the driver’s support for BSON document
35+
- :ref:`scala-documents`: describes the driver’s support for BSON document
3236
representations
3337
- Macros: describes the case classes you can use to represent documents in a collection
3438
- Extended JSON: describes the driver’s support for MongoDB Extended

source/bson/documents.txt

Lines changed: 242 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,242 @@
1+
.. _scala-documents:
2+
3+
=========
4+
Documents
5+
=========
6+
7+
.. facet::
8+
:name: genre
9+
:values: reference
10+
11+
.. meta::
12+
:keywords: representation, storage, codec
13+
14+
.. contents:: On this page
15+
:local:
16+
:backlinks: none
17+
:depth: 2
18+
:class: singlecol
19+
20+
Overview
21+
--------
22+
23+
The {+driver-short+} includes two Scala-specific representations for BSON
24+
documents. Following the convention from the Scala collections library,
25+
there are immutable and mutable implementations of the ``Document`` type. The
26+
underlying implementations of ``Document`` use the type-safe
27+
`BsonDocument <{+api+}/bson/org/bson/BsonDocument.html>`__ class. The BSON classes are available from the
28+
``org.mongodb.scala.bson`` namespace, which includes type aliases and
29+
companion objects. These objects should suffice for many use cases, but
30+
for advanced use cases you may need to use classes from the ``org.bson``
31+
namespace directly.
32+
33+
.. important:: Duplicate Key Names
34+
35+
The server’s behavior regarding duplicate key names in a document is
36+
undefined. When a document with duplicate key names is decoded, the
37+
driver will assign the last value associated with the duplicate key.
38+
Storing such a document will cause the other values to be lost.
39+
40+
.. note::
41+
42+
The Scala ``Document`` classes implement ``TraversableLike[(String,
43+
BsonValue)]`` and the general API mirrors that of a ``Map[String,
44+
BsonValue]`` value. However, unlike ``Map``, implementations of ``TraversableLike``
45+
enable strict type safety as there is no variance in the value type.
46+
47+
``BsonValue`` is the type-safe representation of a BSON type from the
48+
``org.bson`` library and represents specific value types. The most commonly
49+
used value types are as follows:
50+
51+
.. list-table::
52+
:header-rows: 1
53+
:class: compatibility-large
54+
55+
* - BSON Type
56+
- Scala Type
57+
58+
* - ``Document``
59+
- ``org.mongodb.scala.bson.Document``
60+
61+
* - ``Array``
62+
- ``List``
63+
64+
* - ``Date``
65+
- ``Date`` or ``int`` (milliseconds since epoch)
66+
67+
* - ``Boolean``
68+
- ``Boolean``
69+
70+
* - ``Double``
71+
- ``Double``
72+
73+
* - ``Int32``
74+
- ``Integer``
75+
76+
* - ``Int64``
77+
- ``Long``
78+
79+
* - ``String``
80+
- ``String``
81+
82+
* - ``Binary``
83+
- ``Array[Byte]``
84+
85+
* - ``ObjectId``
86+
- ``ObjectId``
87+
88+
* - ``Null``
89+
- ``None``
90+
91+
It is possible to change or extend these mappings, a process described
92+
in the following sections.
93+
94+
The following sections describe the two main ``Document`` classes.
95+
96+
Immutable Documents
97+
-------------------
98+
99+
Similar to the Scala collections library, the immutable class is the preferred
100+
class. For convenience, it is aliased to ``org.mongodb.scala.Document`` and
101+
``org.mongodb.scala.bson.Document`` as well as being available from
102+
``org.mongodb.scala.bson.collection.immutable.Document``.
103+
104+
Instances of this
105+
type are guaranteed to be immutable for everyone. Such a collection will
106+
never change after it is created. Therefore, you can rely on the fact
107+
that accessing the same collection value repeatedly at different points
108+
in time will always yield a collection with the same elements.
109+
110+
.. code-block:: scala
111+
112+
import org.mongodb.scala.bson._
113+
114+
val doc1 = Document("AL" -> BsonString("Alabama"))
115+
val doc2 = doc1 + ("AK" -> BsonString("Alaska"))
116+
val doc3 = doc2 ++ Document("AR" -> BsonString("Arkansas"), "AZ" -> BsonString("Arizona"))
117+
118+
Mutable Documents
119+
-----------------
120+
121+
To get the mutable ``Document`` type, you need to import it explicitly
122+
from ``org.mongodb.scala.collections.mutable.Document``. The mutable
123+
``Document`` can be updated or extended in place. This means you can change,
124+
add, or remove elements of the ``Document`` as a side effect. Similar to Scala
125+
collections, when dealing with mutable types you need to understand
126+
which code changes which collection and when.
127+
128+
.. code-block:: scala
129+
130+
import org.mongodb.scala.bson._
131+
import org.mongodb.scala.bson.collection.mutable.Document
132+
133+
val doc = Document("AL" -> BsonString("Alabama"))
134+
val doc1 = doc + ("AK" -> BsonString("Alaska")) // doc not mutated but new doc created
135+
doc1 ++= Document("AR" -> BsonString("Arkansas"),
136+
"AZ" -> BsonString("Arizona")) // doc1 mutated as ++= changes in place.
137+
138+
Implicit Conversions
139+
--------------------
140+
141+
For many of the ``BsonValue`` types, there are obvious direct mappings from a
142+
Scala type. For example, a ``String`` maps to ``BsonString``, an ``Int`` maps to
143+
``BsonInt32`` and a ``Long`` maps to a ``BsonInt64``. For convenience, these types
144+
can be used directly with ``Document`` types and they are converted by the
145+
contract traits in the ``BsonMagnets`` object. As long as there is an
146+
implicit ``BsonTransformer`` in scope for any given type, then that type can
147+
be converted into a ``BsonValue``.
148+
149+
The following ``BsonTransformers`` are in scope by default:
150+
151+
.. list-table::
152+
:header-rows: 1
153+
:class: compatibility-large
154+
155+
* - Scala Type
156+
- BsonValue
157+
158+
* - ``Boolean``
159+
- ``BsonBoolean``
160+
161+
* - ``String``
162+
- ``BsonString``
163+
164+
* - ``Array[Byte]``
165+
- ``BsonBinary``
166+
167+
* - ``Regex``
168+
- ``BsonRegex``
169+
170+
* - ``Date``
171+
- ``BsonDateTime``
172+
173+
* - ``ObjectId``
174+
- ``BsonObjectId``
175+
176+
* - ``Int``
177+
- ``BsonInt32``
178+
179+
* - ``Long``
180+
- ``BsonInt64``
181+
182+
* - ``Double``
183+
- ``BsonDouble``
184+
185+
* - ``immutable.Document``
186+
- ``BsonDocument``
187+
188+
* - ``mutable.Document``
189+
- ``BsonDocument``
190+
191+
* - ``Option[T]``
192+
- ``BsonValue`` where ``T`` has a ``BsonTransformer``
193+
194+
* - ``Seq[(String, T)]``
195+
- ``BsonDocument`` where ``T`` has a ``BsonTransformer``
196+
197+
* - ``Seq[T]``
198+
- ``BsonArray`` where ``T`` has a ``BsonTransformer``
199+
200+
* - ``BsonValue``
201+
- ``BsonValue``
202+
203+
.. code-block:: scala
204+
205+
import org.mongodb.scala.Document
206+
207+
val doc1 = Document("AL" -> "Alabama")
208+
val doc2 = doc1 + ("AK" -> "Alaska")
209+
val doc3 = doc2 ++ Document("AR" -> "Arkansas", "population" -> 2.966)
210+
211+
This is achieved by making use of the **Magnet Pattern**, which you can
212+
learn more about in the `Magnet Pattern blog post on spray.io
213+
<http://spray.io/blog/2012-12-13-the-magnet-pattern/>`__.
214+
215+
In the API where we would normally expect a single value or a key-value
216+
pair or many key value pairs, such as ``BsonValue``, (``String``, ``BsonValue``) or
217+
``Iterable[(String, BsonValue)]``, we require anything that can become those
218+
types via ``CanBeX`` traits that handle the implicit conversions necessary
219+
to conform to the correct types. These traits are ``CanBeBsonValue``,
220+
``CanBeBsonElement`` and ``CanBeBsonElements``.
221+
222+
One such example is adding a key-value pair to a ``Document`` or a list of
223+
values:
224+
225+
.. code-block:: scala
226+
227+
val doc1 = Document("AL" -> "Alabama")
228+
val doc2 = Document("codes" -> List("AL", "AK", "AR"))
229+
230+
Bson
231+
~~~~
232+
233+
The driver also contains a small but powerful interface called ``Bson``. Any
234+
class that represents a BSON document, whether included in the driver
235+
itself or from a third party, can implement this interface and can then
236+
be used any place in the high-level API where a BSON document is
237+
required. For example:
238+
239+
.. code-block:: scala
240+
241+
collection.find(Document("x" -> 1))
242+
collection.find(Filters.eq("x", 1))

0 commit comments

Comments
 (0)