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); });}