Relational database design to mongoDB/mongoose design Relational database design to mongoDB/mongoose design mongoose mongoose

Relational database design to mongoDB/mongoose design


Mongoose is designed in such a way that you can model your tables relationally with relative ease and populate relational data based on the ref you defined in the schema. The gotcha is that you need to be careful with populating. If you populate too much or nest your populations you will run into performance bottle necks.

Your approach in Edit 1 is largely correct however you usually don't want to populate a remote ref based on a Number or set the _id of a model to a Number since mongo uses it's own hashing mechanism for managing the _id, this would usually be an ObjectId with _id implied. Example as shown below:

var ScoreSchema = new mongoose.Schema({    user : { type: Schema.Types.ObjectId, ref: 'User' },    game : { type: Schema.Types.ObjectId, ref: 'Game' },    score: Number});

If for some reason you need to maintain a number id for your records consider calling it uid or something that won't conflict with mongo / mongoose internals. Good luck!


First of all, you are hitting on some good points here. The beauty of Mongoose is that you can easily connect and bind schemas to a single collection and reference them in other collections, thus getting the best of both relational and non-relational DBs.

Also, you wouldn't have _id as one of you properties, Mongo will add it for you.

I've made some changes to your schemas using the mongoose.Schema.Types.ObjectId type.

var UserSchema = new mongoose.Schema({    username: {        type: String,        index: true,        required: true,        unique: true    },    email: {        type: String,        required: true    },    password: {        type: String,        required: true    },    scores: [{ type: Schema.Types.ObjectId, ref: 'Score' }]});var GameSchema = new mongoose.Schema({    name: String});var LobbySchema = new mongoose.Schema({    _game: {        type: mongoose.Schema.Types.ObjectId,        ref: 'Game'      },    name: String});var ScoreSchema = new mongoose.Schema({    _user : {          type: mongoose.Schema.Types.ObjectId,          ref: 'User'        },    _game : {          type: mongoose.Schema.Types.ObjectId,          ref: 'Game'        },    score: Number});

This will allow you to query your database and populate any referenced collections and objects.

For example:

ScoreSchema.find({_id:##userIdHere##})           .populate('_user')           .populate('_game')             .exec(function(err, foundScore){                   if(err){                      res.send(err)                    } else {                 res.send(foundScore)   }}

This will populate the related user and game properties.


As you edited the post, I think it would be good. At least not bad :)

Check Mongoose Query Population. It's very useful to get related data.

var mongoose = require('mongoose'),    ObjectId = mongoose.Schema.Types.ObjectId// code, code, codefunction something(req, res) {  var id = req.params.id  // test id  return Lobby.findOne({_id: new ObjectId(id)})    .populate('_game')    .exec(function(error, lobby) {       console.log(lobby._game.name);     });}