|
As MongoDB is non-relational (no joins), references ("foreign keys") between documents are generally resolved client-side by additional queries to the server ("linking"). These links are always resolved client-side. Doing this directly/manually can be quite easy and is recommended. There is also a DBRef mechanism which many drivers support which abstracts the linking concept somewhat. Generally though direct/manual links are the recommended approach. Embedding objects is an alternative to linking and is often more appropriate and superior. See the schema design page and also the schema design presentation videos. Simple Direct/Manual LinkingGenerally, manually coded link resolution works just fine and is easy. We simply store the value that is present in _id in some other document in the database and then query it later. For example: > // grab a random blog post: > p = db.postings.findOne(); { "_id" : ObjectId("4b866f08234ae01d21d89604"), "author" : "jim", "title" : "Brewing Methods" } > // get more info on author of post p. this is the "linking" step. > a = db.users.findOne( { _id : p.author } ) { "_id" : "jim", "email" : "jim@gmail.com" } > // inverse: given an author, find all blog posts for the author > db.postings.find( {author : a._id } ) DBRefDBRef is a more formal specification for creating references between documents. DBRefs (generally) include a collection name as well as an object id. Most developers only use DBRefs if the collection can change from one document to the next. If your referenced collection will always be the same, the manual references outlined above are more efficient.
DBRef's have the advantage of allowing optional automatic client-side dereferencing with some drivers. In many cases, you can just get away with storing the _id as a reference then dereferencing manually as detailed in the "Simple Manual References" section above. Syntax for a DBRef reference value is { $ref : <collname>, $id : <idvalue>[, $db : <dbname>] }
where <collname> is the collection name referenced (without the database name), and <idvalue> is the value of the _id field for the object referenced. $db is optional (currently unsupported by many of the drivers) and allows for references to documents in other databases (specified by <dbname>).
The old BSON DBRef datatype is deprecated. DBRef in Different Languages / Drivers C# Use the DBRef class. It takes the collection name and _id as parameters to the constructor. Then you can use the FollowReference method on the Database class to get the referenced document. C++ The C++ driver does not yet provide a facility for automatically traversing DBRefs. However one can do it manually of course. Java Java supports DB references using the DBRef class. Javascript (mongo shell) Example: > x = { name : 'Biology' }
{ "name" : "Biology" }
> db.courses.save(x)
> x
{ "name" : "Biology", "_id" : ObjectId("4b0552b0f0da7d1eb6f126a1") }
> stu = { name : 'Joe', classes : [ new DBRef('courses', x._id) ] }
// or we could write:
// stu = { name : 'Joe', classes : [ {$ref:'courses',$id:x._id} ] }
> db.students.save(stu)
> stu
{
"name" : "Joe",
"classes" : [
{
"$ref" : "courses",
"$id" : ObjectId("4b0552b0f0da7d1eb6f126a1")
}
],
"_id" : ObjectId("4b0552e4f0da7d1eb6f126a2")
}
> stu.classes[0]
{ "$ref" : "courses", "$id" : ObjectId("4b0552b0f0da7d1eb6f126a1") }
> stu.classes[0].fetch()
{ "_id" : ObjectId("4b0552b0f0da7d1eb6f126a1"), "name" : "Biology" }
>
Perl The Perl driver does not provide a facility for automatically traversing DBRefs, but there is a CPAN package for it: MongoDBx::AutoDeref. You can also traverse them manually, of course. PHP PHP supports DB references with the MongoDBRef class, as well as creation and deferencing methods at the database (MongoDB::createDBRef and MongoDB::getDBRef) and collection (MongoCollection::createDBRef and MongoCollection::getDBRef) levels. Python To create a DB reference in python use the bson.dbref.DBRef class. You can also use the dereference method on Database instances to make dereferencing easier. Python also supports auto-ref and auto-deref - check out the auto_reference example. Ruby Ruby also supports DB references using the DBRef class and a dereference method on DB instances. For example: @db = Connection.new.db("blog") @user = @db["users"].save({:name => "Smith"}) @post = @db["posts"].save({:title => "Hello World", :user_id => @user.id}) @ref = DBRef.new("users", @post.user_id) assert_equal @user, @db.dereference(@ref) See Also |

PLEASE POST QUESTIONS IN THE USER GROUPS FORUM. Post non-question comments and helpful hints here.
blog comments powered by Disqus