2

I'm doing a MMO Real-Time Browser game, and I'm storing data using Mongoose (MongoDB).

First of all, I'll show you the structure of my object:

var playerSchema = new Schema({ name: { type: String, required: true, trim: true, index: { unique: true } }, resources: { wood: { type: Number, required: true, default: 500}, stone: { type: Number, required: true, default: 300}, iron: { type: Number, required: true, default: 0}, cereal: { type: Number, required: true, default: 0} }, resourcesPerHour: { woodPerHour: { type: Number, required: true, default: 40}, stonePerHour: { type: Number, required: true, default: 20}, ironPerHour: { type: Number, required: true, default: 0}, }, res: {type: Array, required:true, default: []}, buildings: { type: Array, required: true, default: []}, researches: { type: Array, required: true, default: []} });

As you can see, res, buildings, and researches are arrays. I'm gonna show you one of them (they all have the same structure):

var buildingSchema = new Schema({ id: {type: String, requried: true}, name: { type: String, required: true, trim: true, index: { unique: true } }, level: { type: Number, required: true, default: 0}, scalingValue: {type: Number, required: true, default: 2}, costs: { wood: { type: Number, required: true, default:0}, stone: { type:Number, required:true, default:0}, iron: {type:Number, required:true, default:0}, cereal: {type:Number, required:true, default:0} } });

OK, imagine I have a player, with all data initializated. When I try to update something, I can only update information out of that lists. Look this example:

player.findOne({name:req.session.name}, function(err, doc){ doc.resources.wood -= 200; doc.buildings[id%100].costs.wood *= 2; doc.save(function(err){ if(err)console.log(err); }); }

When I look the model on database, it only stored the resources.wood, not the building[i].costs.wood. I don't know why it's failing, but all objects inside the arrays are created using a new variable, where variable is a Schema (like buildingSchema).

One more thing, I added a console.log(doc.buildings[i].costs.wood); just before the doc.save() and it's ok. So it means all the data is modified fine, but in the doc.saveit only save the 'not-in-list' data.

EDIT: console.log(err); doesn't print nothing, so it means the save function worked.

2 Answers 2

5

When you use the Array type in your schema (same as the Mixed type in the docs), you need to explicitly mark the field as modified or Mongoose won't save any changes you make to it.

doc.markModified('buildings');
doc.save(function(err){
    if(err)console.log(err);
});

The better approach may be to declare buildings as containing an array of buildingSchema:

buildings: [buildingSchema],

That way Mongoose will be able to track the changes you make to the buildings array automatically.

Sign up to request clarification or add additional context in comments.

Comments

1

https://groups.google.com/forum/#!topic/mongoose-orm/5m7ZPkhFyrc

Subdocuments that are not inside of an array are not supported by mongoose. My recommendation is to drop mongoose completely and just use direct queries to the db. You'll find the node native driver is quite easy to use.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.