Automattic / mongoose

MongoDB object modeling designed to work in an asynchronous environment.
https://mongoosejs.com
MIT License
27.01k stars 3.85k forks source link

Embeds documents save only partially #4405

Closed shellka closed 8 years ago

shellka commented 8 years ago

Hello, after fix from 4.5.8: https://github.com/Automattic/mongoose/commit/ed78511e03f81814883b082e22d1038e738a7dda Documents like:

var skillNames = Object.keys(types.skillTypes.list);

var skillSchema = new Schema({
    name: String,
    level: {
        type: Number,
        default: 0
    },
    xp: {
        type: Number,
        default: 0
    }
});

var playerSkillsSchema = Schema({
    playerId: Number,
    skills: (function(availableSkills){
        var result = {};
        availableSkills.forEach(function(skillName){
            result[skillName] = skillSchema;
        });
        return result;
    }(skillNames)),
    version: {
        type: Number,
        default: 0
    }
});

Doesn't save when both params: skill.level and skill.xp saved in the "playerSkills" document, only xp saves.

shellka commented 8 years ago

Document of this schema looks like:

{ "_id" : ObjectId("57aa30eeefeffb1600d3775a"), "playerId" : 1369828, "version" : 0, "skills" : { "surviving" : { "name" : "surviving", "_id" : ObjectId("57aa30eeefeffb1600d37760"), "xp" : 45, "level" : 2 }, "skinning" : { "name" : "skinning", "_id" : ObjectId("57aa30eeefeffb1600d3775f"), "xp" : 0, "level" : 0 }, "leatherworking" : { "name" : "leatherworking", "_id" : ObjectId("57aa30eeefeffb1600d3775e"), "xp" : 0, "level" : 0 }, "lumbering" : { "name" : "lumbering", "_id" : ObjectId("57aa30eeefeffb1600d3775d"), "xp" : 0, "level" : 0 }, "woodworking" : { "name" : "woodworking", "_id" : ObjectId("57aa30eeefeffb1600d3775c"), "xp" : 0, "level" : 0 }, "mining" : { "name" : "mining", "_id" : ObjectId("57aa30eeefeffb1600d3775b"), "xp" : 0, "level" : 0 } }, "__v" : 0 }

smstromb commented 8 years ago

I can confirm that this is also happening for me with 4.5.8:

const ChildObjectSchema = new Schema({
        childProperty1: {
            type: String,
            required: true
        },
        childProperty2: {
            type: String,
            required: true
        },
        childProperty3: {
            type: String,
            required: true
        }
});

const ParentObjectSchema = new Schema({
        parentProperty1: {
            type: String,
            required: true
        },
        parentProperty2: {
            type: String,
            required: true
        },
        child: ChildObjectSchema
}); 

Child Object properties only partially save (just the first property updated):

Parent.findById(id, (err, parent) => {
    parent.parentProperty1 = "foo";
    parent.parentProperty2 = "bar";
    parent.child.childProperty1 =  "ping";
    parent.child.childProperty2 =  "pong";
    parent.child.childProperty3 =  "weeeee";
    parent.save(cb) //childProperty 2 & 3 do not persist to mongoDB but are returned in cb
})

A direct update does work:

Parent.update({
   _id: id
}, {
   $set: {
       parentProperty1: "foo",
       parentProperty2: "bar",
       "child.childProperty1": "ping",
       "child.childProperty2": "pong",
       "child.childProperty3": "weeeee",       
   }
})
ChrisZieba commented 8 years ago

This issue is also happening to us, any extra information needed to help resolve?