Query other attribute in MongoDB with DBRef

800 Views Asked by At

I have two tables' structure in mongodb:

> db.mapping.find()

{ "_id" : ObjectId("52d74f4941538c0b386090af"), 
  "tc" : DBRef("fttc", ObjectId("52d74f4841538c0b3860902e")), 
  "hit" : { "24" : 1, "25" : 1, "26" : 1, "27" : 2}}
...

> db.fttc.find()

{ "_id" : ObjectId("52d74f4841538c0b38609041"), 
  "full" : "build1111_tastcase_20", 
  "tags" : [  "tag_0" ] }
...

> db.mapping.find()[0].tc.fetch().full

build1111_tastcase_1

> db.mapping.find({'tc.$id':ObjectId("52d74f4841538c0b3860902e")})

{ "_id" : ObjectId("52d74f4941538c0b386090a0"), 
  "tc" : DBRef("fttc", ObjectId("52d74f4841538c0b3860902e")),
  "hit" : { "24" : 3, "25" : 3 } }
...

Now, I can get the items whose tc's attribute 'id' is ObjectId("52d74f4841538c0b3860902e").

But, how can I find all the items from mapping, whose tc's attribute 'full' is 'build1111_tastcase_20' ?

Is there any query statement ?

Any help or suggestions will be highly appreciated !

2

There are 2 best solutions below

0
On

Effectively what you are asking for is a join, which is not a supported server-side feature in MongoDB (by design).

Given that your mapping collection currently only has a DBref pointing to the fttc collection, you would have to solve this by using multiple queries and joining the results in your application. This would take three queries on the server side: one to find the mapping doc, one to find the related fttc doc, and then finally a search on fttc for matching documents with the same full attribute.

A better way to approach this in MongoDB would be to denormalise the full attribute that you want to query on, so it ends up saved in both collections.

Your mapping document would then look like:

{ "_id" : ObjectId("52d74f4941538c0b386090a0"), 
  "tc" : DBRef("fttc", ObjectId("52d74f4841538c0b3860902e")),
  "full" : "build1111_tastcase_20",
  "hit" : { "24" : 3, "25" : 3 }
}

Your query to find the related fttc documents becomes a simple find(). Since you are getting data from two collections, you still need to make two queries but this is one less query than the current approach:

doc = db.mapping.findOne({"_id" : ObjectId("52d74f4941538c0b386090a0")})
related = db.fttc.find({"full" : doc.full});
0
On

you access 'full' by db.dereference(db.mapping.find_one()['tc'])['full']