mongoDB: querying for a document that has an object reference

To query two collections with related data the common approach (as at MongoDB 3.0) is to find a list of matching _id values from the first collection which can used with a $in query on the second.

Here's an example using the mongo shell:

// Find _ids for matching locations based on some criteria (eg. "abbrev")
var matches = db.locations.find({ "abbrev": "CAN"}, { _id: 1 })

// Transform matching _id values into an array
var locs = [];
matches.forEach(function(match) { locs.push(match._id) });

// Look for widgets matching the location criteria
db.widgets.find({"loc": {$in : locs} } )

Depending on the driver and/or framework you are using, there may be helper functions to make it easier to populate related data. These helper functions will ultimately result in multiple queries as there is currently no server-side support for joins.

Some examples of frameworks with helpers (not intended to be a comprehensive list):

  • MongooseJS: query population: Node.js Object-Document Model (ODM) framework including declarative schema & query population for relationships
  • Mongoid: relations: Ruby ODM including declarative schema & query population for relationships
  • mongo-views: experimental add-in for the mongo interactive shell adding support for queryable views / virtual collections

You may note that I've said there is currently no server-side support for populating data. There is actually a new $lookup operator being added to the Aggregation Framework in the MongoDB 3.1.x development cycle (which will culminate in the eventual production release series for MongoDB 3.2). For more information see: SERVER-19095 in the MongoDB Jira issue tracker.