Database References

For many use cases in MongoDB, the denormalized data model whererelated data is stored within a single document willbe optimal. However, in some cases, it makes sense to store relatedinformation in separate documents, typically in different collectionsor databases.

Important

MongoDB 3.2 introduces $lookup pipeline stage to performa left outer join to an unsharded collection in the same database.For more information and examples, see $lookup.

Starting in MongoDB 3.4, you can also use $graphLookuppipeline stage to join an unsharded collection to perform recursivesearch. For more information and examples, see$graphLookup.

This page outlines alternative procedures that predate the$lookup and $graphLookup pipeline stages.

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 relateddata. These references are simple and sufficient for most usecases.

  • DBRefs are references from one document to anotherusing the value of the first document’s _id field, collection name,and, optionally, its database name. By including these names, DBRefsallow documents located in multiple collections to be more easily linkedwith documents from a single collection.

To resolve DBRefs, your applicationmust perform additional queries to return the referenceddocuments. Many drivers have helpermethods that form the query for the DBRef automatically. Thedrivers [1] do not automatically resolve DBRefsinto documents.

DBRefs provide a common format and type to represent relationships amongdocuments. The DBRef format also provides common semantics for representinglinks between documents if your database must interact withmultiple frameworks and tools.

Unless you have a compelling reason to use DBRefs, use manualreferences instead.

[1]Some community supported drivers may havealternate behavior and may resolve a DBRef into a documentautomatically.

Manual References

Background

Using manual references is the practice of including onedocument’s _id field in another document. Theapplication can then issue a second query to resolve the referencedfields as needed.

Process

Consider the following operation to insert two documents, using the_id field of the first document as a reference in the seconddocument:

  1. original_id = ObjectId()
  2.  
  3. db.places.insert({
  4. "_id": original_id,
  5. "name": "Broadway Center",
  6. "url": "bc.example.net"
  7. })
  8.  
  9. db.people.insert({
  10. "name": "Erin",
  11. "places_id": original_id,
  12. "url": "bc.example.net/Erin"
  13. })

Then, when a query returns the document from the people collectionyou can, if needed, make a second query for the document referenced bythe places_id field in the places collection.

Use

For nearly every case where you want to store a relationship betweentwo documents, use manual references. Thereferences are simple to create and your application can resolvereferences as needed.

The only limitation of manual linking is that these references do notconvey the database and collection names. If you have documents in asingle collection that relate to documents in more than onecollection, you may need to consider using DBRefs.

DBRefs

Background

DBRefs are a convention for representing a document, ratherthan a specific reference type. They include the name of thecollection, and in some cases the database name, in addition to thevalue from the _id field.

Format

DBRefs have the following fields:

  • $ref
  • The $ref field holds the name of the collection where thereferenced document resides.
  • $id
  • The $id field contains the value of the _id field in thereferenced document.
  • $db
  • Optional.

Contains the name of the database where the referenced documentresides.

Only some drivers support $db references.

Example

DBRef documents resemble the following document:

  1. { "$ref" : <value>, "$id" : <value>, "$db" : <value> }

Consider a document from a collection that stored a DBRef in acreator field:

  1. {
  2. "_id" : ObjectId("5126bbf64aed4daf9e2ab771"),
  3. // .. application fields
  4. "creator" : {
  5. "$ref" : "creators",
  6. "$id" : ObjectId("5126bc054aed4daf9e2ab772"),
  7. "$db" : "users"
  8. }
  9. }

The DBRef in this example points to a document in the creatorscollection of the users database that hasObjectId("5126bc054aed4daf9e2ab772") in its _id field.

Note

The order of fields in the DBRef matters, and you must use the abovesequence when using a DBRef.

Driver Support for DBRefs

DriverDBRef SupportNotes
CNot SupportedYou can traverse references manually.
C++Not SupportedYou can traverse references manually.
C#SupportedPlease see the C# driver pagefor more information.
HaskellNot SupportedYou can traverse references manually.
JavaSupportedPlease see the Java driver pagefor more information.
Node.jsSupportedPlease see the Node.js driver pagefor more information.
PerlSupportedPlease see the Perl driver pagefor more information.
PHPNot SupportedYou can traverse references manually.
PythonSupportedPlease see the PyMongo driver pagefor more information.
RubySupportedPlease see the Ruby driver pagefor more information.
ScalaNot SupportedYou can traverse references manually.

Use

In most cases you should use the manual reference method for connecting two or more relateddocuments. However, if you need to reference documents from multiplecollections, consider using DBRefs.