[MongoDB]: Database References
MongoDB does not support joins. In MongoDB some data is denormalized, or stored with related data in documents 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.
MongoDB applications use one of two methods for relating documents:
-
Manual 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.
-
DBRefs are references from one document to another using the value of the first document’s _idfield, 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 drivers have helper methods that form the query for the DBRef automatically. The drivers 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.
Manual References
Background
Using manual references is the practice of including one document’s _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:
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 manual 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.
DBRefs
Background
DBRefs are a convention for representing a 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 _idfield.
Format
DBRefs have the following fields:
- $ref
- The $ref field holds the name of the collection where the referenced document resides.
- $id
- The $id field contains the value of the _id field in the referenced document.
- $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:
{ "$ref" : <value>, "$id" : <value>, "$db" : <value> }
Consider a document from a collection that stored a DBRef in a creator field:
{
"_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
- C
- The C driver contains no support for DBRefs. You can traverse references manually.
- C++
- The C++ driver contains no support for DBRefs. You can traverse references manually.
- C#
- The C# driver supports DBRefs using the MongoDBRef class and the FetchDBRef method.
- Haskell
- The Haskell driver contains no support for DBRefs. You can traverse references manually.
- Java
- The DBRef class provides support for DBRefs from Java.
- JavaScript
- The mongo shell’s JavaScript interface provides a DBRef.
- Node.js
- The Node.js driver supports DBRefs using the DBRef class and the dereference method.
- Perl
- The Perl driver contains no support for DBRefs. You can traverse references manually or use theMongoDBx::AutoDeref CPAN module.
- PHP
- The PHP driver supports DBRefs, including the optional $db reference, using the MongoDBRef class.
- Python
- The Python driver supports DBRefs using the DBRef class and the dereference method.
- Ruby
- The Ruby driver supports DBRefs using the DBRef class and the dereference method.
- Scala
- The Scala driver contains no support for DBRefs. You can traverse references manually.
Use
In most cases you should use the manual reference method for connecting two or more related documents. However, if you need to reference documents from multiple collections, consider using DBRefs.