dvlchd3
dvlchd3

Reputation: 13

Mongoose Embeded Document Not Saving

For anyone who plays Guild Wars 2, this schema may look familiar. I am attempting to download all items through their API, and am having trouble getting the embedded 'details' property to marshal and/or persist. This is my first stab at using mongoose, so I'm hoping there is a glaringly obvious problem here:

Here is my Schema definition:

var ItemSchema = new Schema({
    _id: Number,
    name: String,
    icon: String,
    description: String,
    type: String,
    rarity: String,
    level: Number,
    vendor_value: Number,
    default_skin: Number,
    flags: [String],
    game_types: [String],
    restrictions: [String],
    details: {                // This is the problem property
        type: String,
        weight_class: String,
        defense: Number,
        infusion_slots: {
            flags: [String],
            item_id: Number
        },
        infix_upgrade: {
            attributes: [{
                attribute: String,
                modifier: Number
            }],
            buff: {
                skill_id: String,
                description: String
            }
        },
        suffix_item_id: Number,
        size: Number,
        no_sell_or_sort: Boolean,
        description: String,
        duration_ms: Number,
        unlock_type: String,
        color_id: Number,
        recipe_id: Number,
        charges: Number,
        flags: [String],
        infusion_upgrade_flags: [String],
        suffix: String,
        bonuses: [String],
        damage_type: String,
        min_power: Number,
        max_power: Number
    }
});

I have attempted to save the incoming objects through both insert and findOneAndUpdate (upsert).

var gwItem = // grab from API.
Item.remove({_id: gwItem.id}).exec();
// At this point, details looks like an object property.
gwItem['_id'] = gwItem.id;
var item = new Item(gwItem);
// At this point, calling item.toObject() shows no 'details' property set...
item.save().exec();  // 'details' not saved here
// Do below in replacement of item.save();
gwItem['$setOnInsert'] = {_id: gwItem.id};
// This saves 'details' property with a value of '[object Object]'...
Item.findOneAndUpdate({_id: gwItem.id}, gwItem, {upsert:true}, function(){});

Example of what the API sends and is populated into 'gwItem' in above code: https://api.guildwars2.com/v2/items/68743

What am I doing wrong?

Upvotes: 0

Views: 68

Answers (1)

Jason Cust
Jason Cust

Reputation: 10899

It's because of how Mongoose defines schemas. Since you used the keyword type as a pathname for details it defines details as a String field and the rest of your paths are options for details. Simply change type: String to type: {type: String} and you should be all set. More info here.

Upvotes: 1

Related Questions