Populate a mongoose model with a field that isn't an id
This is supported since Mongoose 4.5, and is called virtuals population.
You have to define your foreign keys relationships after your schemas definitions and before creating models, like this:
// Schema definitions
BookSchema = new mongoose.Schema({
...,
title: String,
authorId: Number,
...
},
// schema options: Don't forget this option
// if you declare foreign keys for this schema afterwards.
{
toObject: {virtuals:true},
// use if your results might be retrieved as JSON
// see http://stackoverflow.com/q/13133911/488666
//toJSON: {virtuals:true}
});
PersonSchema = new mongoose.Schema({id: Number, ...});
// Foreign keys definitions
BookSchema.virtual('author', {
ref: 'Person',
localField: 'authorId',
foreignField: 'id',
justOne: true // for many-to-1 relationships
});
// Models creation
var Book = mongoose.model('Book', BookSchema);
var Person = mongoose.model('Person', PersonSchema);
// Querying
Book.find({...})
// if you use select() be sure to include the foreign key field !
.select({.... authorId ....})
// use the 'virtual population' name
.populate('author')
.exec(function(err, books) {...})
It seems they enforce to use _id
, and maybe we can customize it in the future.
Here is the issue on Github https://github.com/LearnBoost/mongoose/issues/2562
This is an example of using the $lookup aggregate to populate a model called Invite with the respective User based on the corresponding email
field:
Invite.aggregate(
{ $match: {interview: req.params.interview}},
{ $lookup: {from: 'users', localField: 'email', foreignField: 'email', as: 'user'} }
).exec( function (err, invites) {
if (err) {
next(err);
}
res.json(invites);
}
);
It's probably quite similar to what you're trying to do.