Два вышеупомянутых синтаксиса совершенно разные, в одном фактический поддокумент (дочерние элементы) хранится в родительском документе, а в другом новый документ сохраняется в дочерней коллекции, и только его ссылка сохраняется в родительский документ.
Случай 1:
var childSchema = new Schema({ name: 'string' });
var parentSchema = new Schema({
// Array of subdocuments
children: [childSchema],
// Single nested subdocuments. Caveat: single nested subdocs only work
// in mongoose >= 4.2.0
child: childSchema
});
В этом заданном синтаксисе родительский документ также будет хранить дочерний документ в родительском документе.
Пример документа в родительском собрании будет выглядеть следующим образом:
{
_id : "parent_random_generated_id"
children :[{ _id : "childid1" , name : "Captain America"},
{ _id : "childid2" , name : "Iron Man"},...],
child : {_id : "childid3" , name : "Thor Odinson"},
...
}
Дело 2:
var childSchema = new Schema({ name: 'string' });
mongoose.model('children', childSchema);
var parentSchema = new Schema({
children: {
type: Schema.Types.ObjectId,
ref: 'children'
},
});
В этом синтаксисе дочерние документы будут храниться отдельно, а их ссылочный идентификатор (_id) будет храниться в родительском документе.
Образцы документов в этом случае будут выглядеть примерно так:
// Children documents
{ _id : "childid1" , name : "Captain America"}
{ _id : "childid2" , name : "Iron Man"}
{ _id : "childid3" , name : "Thor Odinson"}
//parent document
{
_id : "parent_random_generated_id"
children :["childid1","childid2",...],
child : "childid3",
...
}
Во втором случае вы можете использовать оператор Mongodb $lookup
для заполнения вложенных документов, когда это необходимо, с помощью mongodb aggregation pipeline
или с помощью .populate('children')
или .populate('child')
для оцифровки конкретного дочернего документа.
Надеюсь, это прояснит ваше сомнение.