WooCaSh
WooCaSh

Reputation: 5212

Mongoose DBRef implementation is not the same like in MongoDB documentation

I have big problem with maybe trivial problem. I'm trying to use reference with mongoose.js for MongoDB database. Let's take a look on this example:

Example code:

https://gist.github.com/hastebrot/1170907

When I run this code I have something like that in my db:

> db.stories.find()
{ 
  "title" : "A man who cooked Nintendo",
  "_creator" :  ObjectId("52e7dc001bdedb703df29b8e"),
  "_id" : ObjectId("52e7dc001bdedb703df29b8f"),
  "fans" : [ ], "__v" : 0
}

> db.people.find()
{
  "name" : "Aaron",
  "age" : 100,
  "_id" : ObjectId("52e7dc001bdedb703df29b8e"),
  "stories" : [ ], "__v" : 0
}

Where is the problem?

In case where I insert data using mongoose and read references using mongoose all is fine. But when db is fetched by Java program with own layer for mongoDB then problem appear.

This Java program add something like that into db (this is another example don't look on not matched field):

//other fields
"user": {
    "$ref": "users",
    "$id": {
        "$oid": "52c6c497c08e6fcf37000001"
    }
}

When we go to documentation of MongoDB (http://docs.mongodb.org/manual/reference/database-references/#dbrefs) we can read that reference property need $ref and $id fields.

Question:

So is it problem with wrong implementation mongoDB DBRef type into mongoose or I'm doing something wrong?

Upvotes: 2

Views: 1575

Answers (1)

Adam Comerford
Adam Comerford

Reputation: 21682

The reference in mongoose is a manual reference, not a dbref (the use of which I will discuss later). At a high level what is going on here is that it is embedding the ObjectId of the person as the value in the _creator field. Then, should you wish to "use" that relationship, say by looking for all stories created by the person named "Aaron", there will effectively be two queries:

  • 1st query will fetch the _id of the person names Aaron from the people collection, that is: db.people.findOne({"name" : "Aaron"})
  • 2nd query will use that _id to look up all stories with that creator, that is: db.stories.find({"creator" : ObjectId("52e7dc001bdedb703df29b8e")})

The ORM (mongoose in this case) is abstracting this for you, and allowing you to define relationships etc. without you having to be aware of what is going on under the covers.

When you are attempting to do this with a native driver outside the ORM you've made a fundamental mistake in terms of how it actually achieves these relationships. It does not use database references, and in general their use is discouraged (see the first note about manual references in the docs), rather it uses something similar to what I described above.

If you wish to emulate the functionality, you should do something similar, and avoid the use of database references.

Upvotes: 4

Related Questions