Pregunta

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.

¿Fue útil?

Solución

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.

Otros consejos

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.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top