Reputation: 9568
I'm having a dynamic data model, with couple of static field and the rest are dynamic. e.g.
var item1 = {
title:'Door',
price: 30,
color:{selected:'blue', options:['blue', 'red']}, // dynamic
material:{selected:'wood', options:['iron', 'wood', 'plastic']}
}
var item2 = {
title:'T-Shirt',
price: 5,
color:{selected:'green', options:['blue', 'green']}, // dynamic
size:{selected:'XL', options:['XL', 'L']} // dynamic
}
The fields that are marked as dynamic are not know on schema definition and new once can appear dynamically. The schema I created looks like this:
var itemSchema = mongoose.Schema({
title: String,
price: Number
});
It seems like Mongoose stores the dynamic fields but on 'find' these fields return as blobs and toJSON()/toObject() drop them. Is there a way to convert them back to sub-docs?
Upvotes: 3
Views: 5042
Reputation: 333
I think that you should use strict option set to false on schema declaration so that other properties added to your document get also saved:
Here, more info: http://mongoosejs.com/docs/guide.html#strict
Regards!
Upvotes: 0
Reputation: 8161
In my experience Mongoose does not save what is not defined in the schema. Based on your itemSchema
, anything other than title
or price
would not be saved.
Based on the code you've provided I'm assuming that color, size, and material may or may not be present but if they are, they all follow the same format: an object with selected
and options
keys. So you might want to try Mongoose Subdocuments
var selectionSchema = new Schema({
selected:String,
options:Array
});
var itemSchema = mongoose.Schema({
title: {type:String, required:true},
price: {type:Number, required:true},
color: selectionSchema,
material: selectionSchema,
size: selectionSchema
});
Notice that color
, material
, and size
keys are not required, this still allows them to be dynamic. If data is present, the key+data will be saved. If no data is present, they key will not be saved either.
UPDATE:
As you mentioned in your comment, you don't know all the dynamic properties upfront. In this case, if you specify a property on the schema as a "blank" object, Mongoose will allow any and all properties on that blank object, like so:
var itemSchema = mongoose.Schema({
title: {type:String, required:true},
price: {type:Number, required:true},
selection:{}
});
Here, the selection
key — being a "blank" object — could hold size
, color
, material
, or any other key. They don't need to be known in advance. You could still use the selectionSchema to enforce keys & values of that sub object.
Upvotes: 1