/
database-references.txt
277 lines (186 loc) · 6.92 KB
/
database-references.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
.. index:: DBRef
.. index:: database references
.. index:: references
.. _database-references:
===================
Database References
===================
.. default-domain:: mongodb
.. contents:: On this page
:local:
:backlinks: none
:depth: 1
:class: singlecol
In MongoDB some data is *denormalized*, or stored with related data in
:term:`documents <document>` to remove the need for joins. However, in
some cases it makes sense to store related information in separate
documents, typically in different collections or databases.
.. important::
Starting in version 3.2, you can use :pipeline:`$lookup` to perform
a left outer join to an unsharded collection in the same database.
For more information and examples, see :pipeline:`$lookup`.
This page outlines alternative procedures that predate the
:pipeline:`$lookup` pipeline stage.
MongoDB applications use one of two methods for relating documents:
- :ref:`Manual references <document-references>` where you save the
``_id`` field of one document in another document as a reference.
Then your application can run a second query to return the related
data. These references are simple and sufficient for most use
cases.
- :ref:`DBRefs <dbref-explanation>` are references from one document to another
using the value of the first document's ``_id`` field, collection name,
and, optionally, its database name. By including these names, DBRefs
allow documents located in multiple collections to be more easily linked
with documents from a single collection.
To resolve DBRefs, your application
must perform additional queries to return the referenced
documents. Many :ecosystem:`drivers </drivers>` have helper
methods that form the query for the DBRef automatically. The
drivers [#official-driver]_ do not *automatically* resolve DBRefs
into documents.
DBRefs provide a common format and type to represent relationships among
documents. The DBRef format also provides common semantics for representing
links between documents if your database must interact with
multiple frameworks and tools.
Unless you have a compelling reason to use DBRefs, use manual
references instead.
.. [#official-driver] Some community supported drivers may have
alternate behavior and may resolve a DBRef into a document
automatically.
.. _document-references:
Manual References
-----------------
Background
~~~~~~~~~~
Using manual references is the practice of including one
:term:`document's <document>` ``_id`` field in another document. The
application can then issue a second query to resolve the referenced
fields as needed.
Process
~~~~~~~
Consider the following operation to insert two documents, using the
``_id`` field of the first document as a reference in the second
document:
.. code-block:: javascript
original_id = ObjectId()
db.places.insert({
"_id": original_id,
"name": "Broadway Center",
"url": "bc.example.net"
})
db.people.insert({
"name": "Erin",
"places_id": original_id,
"url": "bc.example.net/Erin"
})
Then, when a query returns the document from the ``people`` collection
you can, if needed, make a second query for the document referenced by
the ``places_id`` field in the ``places`` collection.
Use
~~~
For nearly every case where you want to store a relationship between
two documents, use :ref:`manual references <document-references>`. The
references are simple to create and your application can resolve
references as needed.
The only limitation of manual linking is that these references do not
convey the database and collection names. If you have documents in a
single collection that relate to documents in more than one
collection, you may need to consider using DBRefs.
.. _dbref-explanation:
DBRefs
------
Background
~~~~~~~~~~
DBRefs are a convention for representing a :term:`document`, rather
than a specific reference type. They include the name of the
collection, and in some cases the database name, in addition to the
value from the ``_id`` field.
Format
~~~~~~
DBRefs have the following fields:
.. describe:: $ref
The ``$ref`` field holds the name of the collection where the
referenced document resides.
.. describe:: $id
The ``$id`` field contains the value of the ``_id`` field in the
referenced document.
.. describe:: $db
*Optional.*
Contains the name of the database where the referenced document
resides.
Only some drivers support ``$db`` references.
.. example::
DBRef documents resemble the following document:
.. code-block:: javascript
{ "$ref" : <value>, "$id" : <value>, "$db" : <value> }
Consider a document from a collection that stored a DBRef in a
``creator`` field:
.. code-block:: javascript
{
"_id" : ObjectId("5126bbf64aed4daf9e2ab771"),
// .. application fields
"creator" : {
"$ref" : "creators",
"$id" : ObjectId("5126bc054aed4daf9e2ab772"),
"$db" : "users"
}
}
The DBRef in this example points to a document in the ``creators``
collection of the ``users`` database that has
``ObjectId("5126bc054aed4daf9e2ab772")`` in its ``_id`` field.
.. note::
The order of fields in the DBRef matters, and you must use the above
sequence when using a DBRef.
Driver Support for DBRefs
~~~~~~~~~~~~~~~~~~~~~~~~~
.. list-table::
:header-rows: 1
:widths: 20 25 80
* - Driver
- DBRef Support
- Notes
* - **C**
- Not Supported
- You can traverse references manually.
* - **C++**
- Not Supported
- You can traverse references manually.
* - **C#**
- Supported
- Please see the :ecosystem:`C# driver page </drivers/csharp/>`
for more information.
* - **Haskell**
- Not Supported
- You can traverse references manually.
* - **Java**
- Supported
- Please see the :ecosystem:`Java driver page </drivers/java/>`
for more information.
* - **Node.js**
- Supported
- Please see the :ecosystem:`Node.js driver page </drivers/node/>`
for more information.
* - **Perl**
- Supported
- Please see the :ecosystem:`Perl driver page </drivers/perl/>`
for more information.
* - **PHP**
- Not Supported
- You can traverse references manually.
* - **Python**
- Supported
- Please see the :ecosystem:`PyMongo driver page </drivers/pymongo/>`
for more information.
* - **Ruby**
- Supported
- Please see the `Ruby driver page <https://docs.mongodb.com/ruby-driver/current/>`__
for more information.
* - **Scala**
- Not Supported
- You can traverse references manually.
Use
~~~
In most cases you should use the :ref:`manual reference
<document-references>` method for connecting two or more related
documents. However, if you need to reference documents from multiple
collections, consider using DBRefs.