Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

what is the real purpose of $ref (DBRef) in MongoDb

Tags:

mongodb

I want to use mongo for my app, and while I was thinking about designing issues, I came up with question, so what are the advantages/purposes of DBRef?

for example:

> names = ['apple', 'banana', 'orange', 'peach', 'pineapple']
[ "apple", "banana", "orange", "peach", "pineapple" ]
> for (i=0; i<5; i++) {
... db.fruits.insert({_id:i, name:names[i]})
... }
> db.fruits.find()
{ "_id" : 0, "name" : "apple" }
{ "_id" : 1, "name" : "banana" }
{ "_id" : 2, "name" : "orange" }
{ "_id" : 3, "name" : "peach" }
{ "_id" : 4, "name" : "pineapple" }

and I want to store those fruits in a basket collection:

> db.basket.insert({_id:1, items:[ {$ref:'fruits', $id:1}, {$ref:'fruits', $id:3} ] })
> db.basket.insert({_id:2, items:[{fruit_id: 1}, {fruit_id: 3}]})
> db.basket.find()
{ "_id" : 1, "items" : [ DBRef("fruits", 1), DBRef("fruits", 3) ] }
{ "_id" : 2, "items" : [ { "fruit_id" : 1 }, { "fruit_id" : 3 } ] }

What are the real difference between those two techniques? For me it looks like using DBRef you just have to insert more data without any advantages.... Please correct me if I'm wrong.

like image 836
Vor Avatar asked Feb 12 '13 05:02

Vor


People also ask

What is the use of @DBRef?

DBRefs are references from one document to another using the value of the first document's _id field, collection name, and, optionally, its database name, as well as any other fields. DBRefs allow you to more easily reference documents stored in multiple collections or databases.

Should I use DBRef?

Basically, I would say that you should only use those DBrefs if the linked document can be of variable type. If it's static then you're stuck with _id-references and maybe your own lazy loader functionality, so you don't repeat yourself.

How do you link collections in MongoDB?

For performing MongoDB Join two collections, you must use the $lookup operator. It is defined as a stage that executes a left outer join with another collection and aids in filtering data from joined documents. For example, if a user requires all grades from all students, then the below query can be written: Students.


2 Answers

Basically a DBRef is a self describing ObjectID which a client side helper, which exists in all drivers (I think all), provides the ability within your application to get related rows easily.

They are not:

  • JOINs
  • Cascadeable relations
  • Server-side relations
  • Resolved Server-side

They also are not used within Map Reduce, the functionality was taken out due to complications with sharding.

It is not always great to use these though, for one they take quite a bit of space if you know the collection that is related to that row in comparison to just storing the ObjectID. Not only that but due to how they are resolved each related record needs to be lazy loaded one by one instead if being able to form a range (easily) to query for related rows all in one go, so they can increase the amount of queries you make to the database as well, in turn increasing cursors.

like image 184
Sammaye Avatar answered Nov 09 '22 18:11

Sammaye


From "MongoDB: The Definitive Guide" DBRefs aren't necessary and storing a MongoID is more lightweight, but DBRefs offer some interesting functionality like the following:

Loading each DBRef in a document:

var note = db.notes.findOne({"_id":20});
note.references.forEach(function(ref) {
  printjson(db[ref.$ref].findOne({"_id": ref.$id}));
});

They're also helpful if the references are stored across different collections and databases as the DBRef contains that info. If you use a MongoID you'd have to remember which DB and collection the MongoID is in reference to.

In your example a basket document's items array might contain references in the fruits collection, but also the vegetables collect. A DBRef would actually be handy in this case.

like image 36
SomethingOn Avatar answered Nov 09 '22 18:11

SomethingOn