31

Using the DBREF datatype in MongoDB, a document may look like as shown below. But having the $ref field in every row feels redundant as every row obviously points to the users collection.

Is there a way to reference other documents without having the somewhat redundant $ref-field?

{
    $id: {$oid : "4f4603820e25f4c515000001"},
    title:   "User group",
    users: [ 
        {_id: {$ref: "users", $id: { $oid: "4f44af6a024342300e000002"}}, isAdmin: true }
    ]
],
Martin Konecny
  • 57,827
  • 19
  • 139
  • 159
Industrial
  • 41,400
  • 69
  • 194
  • 289
  • 4
    is there any specific reason why you are not using the simple Direct/Manual Linking (just putting the ObjectId as suggested below)? –  Feb 23 '12 at 11:51

3 Answers3

48

Dbref in my opinion should be avoided when work with mongodb, at least if you work with big systems that require scalability.

As i know all drivers make additional request to load DBRef, so it's not 'join' within database, it is very expensive.

Is there a way to reference other documents without having the somewhat redundant $ref-field?

Yes, keep references in the mind, create naming conventions for 'foreign keys' (something like RefUserId or just UserId) and store just id of referenced document. Load referenced documents yourself when needed. Also keep your eyes open for any denormalization, embedding you can do, because it's usually greatly improve performance.

Andrew Orsich
  • 52,935
  • 16
  • 139
  • 134
  • 3
    It is not a really an issue of using a DBRef or just the _id but how you resolve them with link semantics. If you have non-homogenious references (to multiple collections) then you will need both the collection and the _id == DBRef. – Scott Hernandez Feb 23 '12 at 15:30
  • 1
    Just to repeat Scott a little: if you are referencing objects in the same collection you can just use an ObjectId field – Nic Cottrell Feb 23 '12 at 18:22
  • so in future updating is more expensive ? because updating not refrenced need to update entire collection hmm ? – babak faghihian Nov 15 '15 at 13:02
  • In Doctrine (Mongo) you need to specifiy storeAs="dbRef" in order to enable STI (single table inheritance). storeAs="id"/simple="true" doesn't work in such a scenario so there are use cases – KAGRAN22 Jan 09 '18 at 12:00
  • If there is an alternative to MongoDb that is able to handle document references in a better way, please let me know: https://softwarerecs.stackexchange.com/questions/81175/is-there-an-alternative-to-mongodb-that-allows-to-easily-resolve-document-refere – Stefan Nov 08 '21 at 08:18
6

Unless you use driver specific methods for accessing dbref, it should be unnecessary.

In cases where you're managing the join manually (i.e. you know which other collection to "join" to), storing just the ObjectId is enough.

zulkamal
  • 578
  • 1
  • 4
  • 17
4

From the docs:

Manual references are an alternative, and the docs say manual references are preferable to DBREFs (though I'm not sure why). DBREFs are helpful when the referenced object lives in another database or where the collection name would not otherwise be obvious.

Denormalization/embedding is preferable to any kind of linking because then you get atomic updates and don't need to re-query for the related data.

Community
  • 1
  • 1
Max Heiber
  • 14,346
  • 12
  • 59
  • 97