I'm trying to create a schema in Mongoose that have a map (object, associative array, key-value pairs), but no success so far.
The documents of my schema must be something like this:
{
"_id": ObjectId("..."),
"groups"
{
"groupA":
{
"value1": "...",
"value2": "..."
},
"groupB":
{
"value3": "...",
},
"groupC":
{
"value4": "...",
"value5": "...",
},
...
}
}
groups is as object with a variable number of keys. I don't know those keys ahead of time as it'll be create by the user.
Every entry in groups is another object. As before, I don't know the key identifiers, but I know that the values are String (or Boolean, or Number, doesn't matter).
Of course, those keys are Strings.
Is it even possible (is there anyway to build such schema/model) in Mongoose?
Best practice is to keep any dynamic data out of your field names. The typical approach for a use case like this is to make groups
an array and move the name of the group into a name
field of the contained objects. Then you can use the Mixed
type to contain the user-defined set of values:
{
"_id": ObjectId("..."),
"groups":
[
{
name: "groupA",
values: {
"value1": "...",
"value2": "..."
}
},
{
name: "groupB",
values: {
"value3": "..."
}
},
{
name: "groupC",
values: {
"value4": "...",
"value5": "..."
}
},
...
]
}
You'd define the schema as:
var schema = new Schema({
groups: [{
name: String,
values: Schema.Types.Mixed
}]
});
Map is supported from version 5.1 - http://mongoosejs.com/docs/schematypes.html#maps
Looks like somebody made a plugin, Hooray!
https://www.npmjs.com/package/mongoose-map
Once you install and configure according to the readme you can just do {groups:[MongooseMap]}...
Have you tried something like this:
var schema = new mongoose.Schema({
groups: [mongoose.Schema.Types.Mixed]
});
Reference: Mongoose Schema Types
Edit, given my comments below, and riffing on the answer before mine, let's assume that all values are of type string (I had understood that they might be anything):
var schema = new mongoose.Schema({
groups:[{
name: String,
values:[String]
}]
});
Edit #2: Assuming that "value1" is a placeholder for some more meaningful name and assuming that the number of member names is finite, as long as they are not required, then you can put them all in your schema, so instead of the array version, you should be able to do this:
var schema = new mongoose.Schema({
groups:[{
name: String,
value1: String,
value2: String,
value3: String,
value4: String,
value5: String
}]
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With