How to populate nested Mongoose embedded documents

2020-05-21 06:49发布

问题:

I have read and re-read several posts about embedded and linked documents in Mongoose. Based upon what I have read, I have concluded that it would be best to have schema structure similar to the following:

var CategoriesSchema = new Schema({
    year            :    {type: Number, index: true},
    make            :    {type: String, index: true},
    model            :    {type: String, index: true},
    body            :    {type: String, index: true}
});

var ColorsSchema = new Schema({
    name            :    String,
    id                :    String,
    surcharge        :    Number
});

var MaterialsSchema = new Schema({
    name                :    {type: String, index: true},
    surcharge            :    String,
    colors                :    [ColorsSchema]
});

var StyleSchema = new Schema({
    name                :    {type: String, index: true},
    surcharge            :    String,
    materials            :    [MaterialsSchema]
});

var CatalogSchema = new Schema({
    name                 :    {type: String, index: true},
    referenceId            :    ObjectId,
    pattern                :    String,
    categories            :    [CategoriesSchema],
    description            :    String,
    specifications        :    String,
    price                :    String,
    cost                :    String,
    pattern                :    String,
    thumbnailPath        :    String,
    primaryImagePath    :    String,
    styles                :    [StyleSchema]
});

mongoose.connect('mongodb://127.0.0.1:27017/sc');
exports.Catalog = mongoose.model('Catalog', CatalogSchema);

The data defined in CategoriesSchema, ColorsSchema and MaterialsSchema won't change very often, if ever. I decided it would be better to have all the data in the Catalog model because while there are multiple categories, colors and materials, there won't be that many and I don't need to find any of them independent of the Catalog.

But I am totally confused about saving data to the model. Here's where I get stumped:

var item = new Catalog;
item.name = "Seat 1003";
item.pattern = "91003";
item.categories.push({year: 1998, make: 'Toyota', model: 'Camry', body: 'sedan' });
item.styles.push({name: 'regular', surcharge: 10.00, materials(?????)});

item.save(function(err){

});

With an nested embedded schema like this, how to I get data into the materials and colors embedded documents?

the .push() method doesn't seem to be available for the nested documents.

回答1:

The array of embedded documents does have the push method. Simply add Embedded Documents after initially creating the item:

var item = new Catalog;
item.name = "Seat 1003";
item.pattern = "91003";
item.categories.push({year: 1998, make: 'Toyota', model: 'Camry', body: 'sedan' });

var color = new Color({name: 'color regular', id: '2asdfasdfad', surcharge: 10.00});
var material = new Material({name: 'material regular', surcharge: 10.00});
var style = new Style({name: 'regular', surcharge: 10.00});

then you can push each embedded doc into their parents:

material.colors.push(color);
style.materials.push(material);
item.styles.push(style);

Then you can save the entire object the database as you where already doing:

item.save(function(err){});

That's it! And you have Embedded DocumentArrays.

A few other notes about your code, you have pattern twice in your Catalog model. And in order to access your other model types, you'll need to also export those:

exports.Catalog = mongoose.model('Catalog', CatalogSchema);
exports.Color = mongoose.model('Colors', ColorsSchema);
exports.Material = mongoose.model('Materials', MaterialsSchema);
exports.Style = mongoose.model('Style', StyleSchema);