There are two ways to relate documents in mongo:
Embedded
Referenced
Embedded is that your collection has an attribute that contains all the data of another model, example:
{
_id: ObjectId('...'),
name: 'test',
data: {
data1: '',
data2: 100,
data3: [],
dataN: {}
}
}
And referenced using the previous example would be:
{
_id: ObjectId('...'),
name: 'test',
data: objectId('...')
}
What is the best way? It depends if your queries will be heavy and will affect the performance, for example if you only want the names, why load all the embedded info? You can say that you can make filters, but by doing that, Mongo first loads the entire document and then filters it which would be affecting the performance anyway. And well, other criteria are if the relationship of your documents is essential for your app to fulfill its function. There may be other criteria, it depends a lot on the requirements and the development team.
If it is by reference, for queries with populate () to work, the id of the referenced document must be of the ObjectId type, otherwise, it will not work.
The example you put:
{id_a : '2der45g', data : 'etc'}
If you have it that way, for mongo the _id is a String, not an ObjectId. It is a lot of difference because the shape of each one is based on different bytes.
When you make your model, you must declare its type as ObjectId and indicate with which other model it refers. I'll give you an example but I'll leave you here the mongoose documentation
var mongoose = require('mongoose')
, Schema = mongoose.Schema
var personSchema = Schema({
_id : Number,
name : String,
age : Number,
stories : [{ type: Schema.Types.ObjectId, ref: 'Story' }]
});
var storySchema = Schema({
_creator : { type: Number, ref: 'Person' },
title : String,
fans : [{ type: Number, ref: 'Person' }]
});
var Story = mongoose.model('Story', storySchema);
var Person = mongoose.model('Person', personSchema);
With that you can now use populate ():
Story.
findOne({ title: 'Once upon a timex.' }).
populate('_creator').
exec(function (err, story) {
if (err) return handleError(err);
console.log('The creator is %s', story._creator.name);
// prints "The creator is Aaron"
});
On the other hand, if it is an embedded relationship, just find () and access the attribute that contains the information you want, but let's say that most of the time you want to do it by reference, it depends on your requirements and if you get to use it, there must be good reasons.
In conclusion, check how you are declaring your models so that associating them is possible, you can use these examples to make a test and then adapt it to your models.